From: <sag...@us...> - 2011-08-22 18:21:48
|
Revision: 993 http://modplug.svn.sourceforge.net/modplug/?rev=993&view=rev Author: saga-games Date: 2011-08-22 18:21:40 +0000 (Mon, 22 Aug 2011) Log Message: ----------- [Mod] Project settings: Changed exception handling style (bloats EXE a bit, but catches exceptions in VST plugins again) [Mod] If an unhandled exception is encountered, a minidump is created. [Ref] Moved ACM code to separate file. [Mod] OpenMPT: Version is now 1.20.00.11 Modified Paths: -------------- trunk/OpenMPT/mptrack/Mod2wave.cpp trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/mptrack/Mptrack.h trunk/OpenMPT/mptrack/mptrack.vcproj trunk/OpenMPT/mptrack/mptrack_08.vcproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters trunk/OpenMPT/mptrack/version.h Added Paths: ----------- trunk/OpenMPT/mptrack/ACMConvert.cpp trunk/OpenMPT/mptrack/ACMConvert.h Added: trunk/OpenMPT/mptrack/ACMConvert.cpp =================================================================== --- trunk/OpenMPT/mptrack/ACMConvert.cpp (rev 0) +++ trunk/OpenMPT/mptrack/ACMConvert.cpp 2011-08-22 18:21:40 UTC (rev 993) @@ -0,0 +1,544 @@ +/* + * + * ACMConvert.cpp + * -------------- + * Purpose: MPEG Layer-3 Functions through ACM - access to LAMEenc and BLADEenc is emulated through the ACM interface + * Notes : (currently none) + * Authors: Olivier Lapicque + * OpenMPT Devs + * + */ + + +#include "stdafx.h" +#include "bladedll.h" +#include "Mptrack.h" +#include "ACMConvert.h" + + +typedef struct BLADEENCSTREAMINFO +{ + BE_CONFIG beCfg; + LONGLONG dummy; + DWORD dwInputSamples; + DWORD dwOutputSamples; + HBE_STREAM hBeStream; + SHORT *pPCMBuffer; + DWORD dwReadPos; +} BLADEENCSTREAMINFO, *PBLADEENCSTREAMINFO; + +static PBLADEENCSTREAMINFO gpbeBladeCfg = NULL; +static PBLADEENCSTREAMINFO gpbeLameCfg = NULL; +BOOL ACMConvert::layer3Present = FALSE; + + +#define TRAP_ACM_FAULTS + +#ifdef TRAP_ACM_FAULTS +void ACMConvert::AcmExceptionHandler() +//------------------------------------ +{ + theApp.GetACMConvert().m_hACMInst = NULL; + theApp.WriteProfileInt("Settings", "DisableACM", 1); +} +#endif + +BOOL ACMConvert::InitializeACM(BOOL bNoAcm) +//----------------------------------------- +{ + DWORD (ACMAPI *pfnAcmGetVersion)(void); + DWORD dwVersion; + UINT fuErrorMode; + BOOL bOk = FALSE; + + fuErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX); + try { + m_hBladeEnc = LoadLibrary(TEXT("BLADEENC.DLL")); + m_hLameEnc = LoadLibrary(TEXT("LAME_ENC.DLL")); + } catch(...) {} + if (!bNoAcm) + { +#ifdef TRAP_ACM_FAULTS + try { +#endif + m_hACMInst = LoadLibrary(TEXT("MSACM32.DLL")); +#ifdef TRAP_ACM_FAULTS + } catch(...) {} +#endif + } + SetErrorMode(fuErrorMode); + if (m_hBladeEnc != NULL) + { + BEVERSION pfnBeVersion = (BEVERSION)GetProcAddress(m_hBladeEnc, TEXT_BEVERSION); + if (!pfnBeVersion) + { + FreeLibrary(m_hBladeEnc); + m_hBladeEnc = NULL; + } else + { + layer3Present = TRUE; + bOk = TRUE; + } + } + if (m_hLameEnc != NULL) + { + BEVERSION pfnBeVersion = (BEVERSION)GetProcAddress(m_hLameEnc, TEXT_BEVERSION); + if (!pfnBeVersion) + { + FreeLibrary(m_hLameEnc); + m_hLameEnc = NULL; + } else + { + layer3Present = TRUE; + bOk = TRUE; + } + } + if ((m_hACMInst < (HINSTANCE)HINSTANCE_ERROR) || (!m_hACMInst)) + { + m_hACMInst = NULL; + return bOk; + } +#ifdef TRAP_ACM_FAULTS + try { +#endif + *(FARPROC *)&pfnAcmGetVersion = GetProcAddress(m_hACMInst, "acmGetVersion"); + dwVersion = 0; + if (pfnAcmGetVersion) dwVersion = pfnAcmGetVersion(); + if (HIWORD(dwVersion) < 0x0200) + { + FreeLibrary(m_hACMInst); + m_hACMInst = NULL; + return bOk; + } + // Load Function Pointers + m_pfnAcmFormatEnum = (PFNACMFORMATENUM)GetProcAddress(m_hACMInst, "acmFormatEnumA"); + // Enumerate formats + if (m_pfnAcmFormatEnum) + { + ACMFORMATDETAILS afd; + BYTE wfx[256]; + WAVEFORMATEX *pwfx = (WAVEFORMATEX *)&wfx; + + MemsetZero(afd); + MemsetZero(*pwfx); + afd.cbStruct = sizeof(ACMFORMATDETAILS); + afd.dwFormatTag = WAVE_FORMAT_PCM; + afd.pwfx = pwfx; + afd.cbwfx = sizeof(wfx); + pwfx->wFormatTag = WAVE_FORMAT_PCM; + pwfx->nChannels = 2; + pwfx->nSamplesPerSec = 44100; + pwfx->wBitsPerSample = 16; + pwfx->nBlockAlign = (WORD)((pwfx->nChannels * pwfx->wBitsPerSample) / 8); + pwfx->nAvgBytesPerSec = pwfx->nSamplesPerSec * pwfx->nBlockAlign; + m_pfnAcmFormatEnum(NULL, &afd, AcmFormatEnumCB, NULL, ACM_FORMATENUMF_CONVERT); + } +#ifdef TRAP_ACM_FAULTS + } catch(...){} +#endif + return TRUE; +} + + +BOOL ACMConvert::UninitializeACM() +//-------------------------------- +{ + if (m_hACMInst) + { + FreeLibrary(m_hACMInst); + m_hACMInst = NULL; + } + if (m_hLameEnc) + { + FreeLibrary(m_hLameEnc); + m_hLameEnc = NULL; + } + if (m_hBladeEnc) + { + FreeLibrary(m_hBladeEnc); + m_hBladeEnc = NULL; + } + return TRUE; +} + + +MMRESULT ACMConvert::AcmFormatEnum(HACMDRIVER had, LPACMFORMATDETAILSA pafd, ACMFORMATENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum) +//---------------------------------------------------------------------------------------------------------------------------------------- +{ + MMRESULT err = MMSYSERR_INVALPARAM; + if ((m_hBladeEnc) || (m_hLameEnc)) + { + HACMDRIVER hBlade = (HACMDRIVER)&m_hBladeEnc; + HACMDRIVER hLame = (HACMDRIVER)&m_hLameEnc; + if (((had == hBlade) || (had == hLame) || (had == NULL)) && (pafd) && (fnCallback) + && (fdwEnum & ACM_FORMATENUMF_CONVERT) && (pafd->dwFormatTag == WAVE_FORMAT_PCM)) + { + ACMFORMATDETAILS afd; + MPEGLAYER3WAVEFORMAT wfx; + + afd.dwFormatIndex = 0; + for (UINT iFmt=0; iFmt<0x40; iFmt++) + { + afd.cbStruct = sizeof(afd); + afd.dwFormatTag = WAVE_FORMAT_MPEGLAYER3; + afd.fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC; + afd.pwfx = (LPWAVEFORMATEX)&wfx; + afd.cbwfx = sizeof(wfx); + wfx.wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3; + wfx.wfx.nChannels = (WORD)((iFmt & 0x20) ? 1 : 2); + wfx.wfx.nSamplesPerSec = 0; + wfx.wfx.nBlockAlign = 1; + wfx.wfx.wBitsPerSample = 0; + wfx.wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES; + wfx.wID = MPEGLAYER3_ID_MPEG; + wfx.fdwFlags = MPEGLAYER3_FLAG_PADDING_ISO; + wfx.nBlockSize = 384; + wfx.nFramesPerBlock = 1; + wfx.nCodecDelay = 1000; + switch((iFmt >> 3) & 0x03) + { + case 0x00: wfx.wfx.nSamplesPerSec = 48000; break; + case 0x01: wfx.wfx.nSamplesPerSec = 44100; break; + case 0x02: wfx.wfx.nSamplesPerSec = 32000; break; + } + switch(iFmt & 7) + { + case 5: wfx.wfx.nAvgBytesPerSec = 320/8; break; + case 4: wfx.wfx.nAvgBytesPerSec = 64/8; break; + case 3: wfx.wfx.nAvgBytesPerSec = 96/8; break; + case 2: wfx.wfx.nAvgBytesPerSec = 128/8; break; + case 1: if (wfx.wfx.nChannels == 2) { wfx.wfx.nAvgBytesPerSec = 192/8; break; } + case 0: if (wfx.wfx.nChannels == 2) { wfx.wfx.nAvgBytesPerSec = 256/8; break; } + default: wfx.wfx.nSamplesPerSec = 0; + } + wsprintf(afd.szFormat, "%dkbps, %dHz, %s", wfx.wfx.nAvgBytesPerSec*8, wfx.wfx.nSamplesPerSec, (wfx.wfx.nChannels == 2) ? "stereo" : "mono"); + if (wfx.wfx.nSamplesPerSec) + { + if (m_hBladeEnc) fnCallback((HACMDRIVERID)hBlade, &afd, dwInstance, ACMDRIVERDETAILS_SUPPORTF_CODEC); + if (m_hLameEnc) fnCallback((HACMDRIVERID)hLame, &afd, dwInstance, ACMDRIVERDETAILS_SUPPORTF_CODEC); + afd.dwFormatIndex++; + } + } + err = MMSYSERR_NOERROR; + } + } + if (m_pfnAcmFormatEnum) + { + err = m_pfnAcmFormatEnum(had, pafd, fnCallback, dwInstance, fdwEnum); + } + return err; +} + + +BOOL ACMConvert::AcmFormatEnumCB(HACMDRIVERID, LPACMFORMATDETAILS pafd, DWORD, DWORD fdwSupport) +//---------------------------------------------------------------------------------------------- +{ + if ((pafd) && (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC)) + { + if (pafd->dwFormatTag == WAVE_FORMAT_MPEGLAYER3) layer3Present = TRUE; + } + return TRUE; +} + + +MMRESULT ACMConvert::AcmDriverOpen(LPHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen) +//-------------------------------------------------------------------------------------- +{ + if ((m_hBladeEnc) && (hadid == (HACMDRIVERID)&m_hBladeEnc)) + { + *phad = (HACMDRIVER)&m_hBladeEnc; + return MMSYSERR_NOERROR; + } + if ((m_hLameEnc) && (hadid == (HACMDRIVERID)&m_hLameEnc)) + { + *phad = (HACMDRIVER)&m_hLameEnc; + return MMSYSERR_NOERROR; + } + if (m_hACMInst) + { + PFNACMDRIVEROPEN pfnAcmDriverOpen = (PFNACMDRIVEROPEN)GetProcAddress(m_hACMInst, "acmDriverOpen"); + if (pfnAcmDriverOpen) return pfnAcmDriverOpen(phad, hadid, fdwOpen); + } + return MMSYSERR_INVALPARAM; +} + + +MMRESULT ACMConvert::AcmDriverClose(HACMDRIVER had, DWORD fdwClose) +//----------------------------------------------------------------- +{ + if ((m_hBladeEnc) && (had == (HACMDRIVER)&m_hBladeEnc)) + { + return MMSYSERR_NOERROR; + } + if ((m_hLameEnc) && (had == (HACMDRIVER)&m_hLameEnc)) + { + return MMSYSERR_NOERROR; + } + if (m_hACMInst) + { + PFNACMDRIVERCLOSE pfnAcmDriverClose = (PFNACMDRIVERCLOSE)GetProcAddress(m_hACMInst, "acmDriverClose"); + if (pfnAcmDriverClose) return pfnAcmDriverClose(had, fdwClose); + } + return MMSYSERR_INVALPARAM; +} + + +MMRESULT ACMConvert::AcmDriverDetails(HACMDRIVERID hadid, LPACMDRIVERDETAILS padd, DWORD fdwDetails) +//-------------------------------------------------------------------------------------------------- +{ + if (((m_hBladeEnc) && (hadid == (HACMDRIVERID)(&m_hBladeEnc))) + || ((m_hLameEnc) && (hadid == (HACMDRIVERID)(&m_hLameEnc)))) + { + if (!padd) return MMSYSERR_INVALPARAM; + padd->cbStruct = sizeof(ACMDRIVERDETAILS); + padd->fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC; + padd->fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED; + padd->wMid = 0; + padd->wPid = 0; + padd->vdwACM = 0x04020000; + padd->vdwDriver = 0x04020000; + padd->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC; + padd->cFormatTags = 1; + padd->cFilterTags = 0; + padd->hicon = NULL; + strcpy(padd->szShortName, (hadid == (HACMDRIVERID)(&m_hBladeEnc)) ? "BladeEnc MP3" : "LAME Encoder"); + strcpy(padd->szLongName, padd->szShortName); + padd->szCopyright[0] = 0; + padd->szLicensing[0] = 0; + padd->szFeatures[0] = 0; + return MMSYSERR_NOERROR; + } + if (m_hACMInst) + { + PFNACMDRIVERDETAILS pfnAcmDriverDetails = (PFNACMDRIVERDETAILS)GetProcAddress(m_hACMInst, "acmDriverDetailsA"); + if (pfnAcmDriverDetails) return pfnAcmDriverDetails(hadid, padd, fdwDetails); + } + return MMSYSERR_INVALPARAM; +} + + +MMRESULT ACMConvert::AcmStreamOpen( + LPHACMSTREAM phas, // pointer to stream handle + HACMDRIVER had, // optional driver handle + LPWAVEFORMATEX pwfxSrc, // source format to convert + LPWAVEFORMATEX pwfxDst, // required destination format + LPWAVEFILTER pwfltr, // optional filter + DWORD dwCallback, // callback + DWORD dwInstance, // callback instance data + DWORD fdwOpen) // ACM_STREAMOPENF_* and CALLBACK_* +//-------------------------------------------------------------------------- +{ + PBLADEENCSTREAMINFO *ppbeCfg = NULL; + HINSTANCE hLib = NULL; + + if ((m_hBladeEnc) && (had == (HACMDRIVER)&m_hBladeEnc)) + { + ppbeCfg = &gpbeBladeCfg; + hLib = m_hBladeEnc; + } + if ((m_hLameEnc) && (had == (HACMDRIVER)&m_hLameEnc)) + { + ppbeCfg = &gpbeLameCfg; + hLib = m_hLameEnc; + } + if ((ppbeCfg) && (hLib)) + { + BEINITSTREAM pfnbeInitStream = (BEINITSTREAM)GetProcAddress(hLib, TEXT_BEINITSTREAM); + if (!pfnbeInitStream) return MMSYSERR_INVALPARAM; + PBLADEENCSTREAMINFO pbeCfg = new BLADEENCSTREAMINFO; + if ((pbeCfg) && (pwfxSrc) && (pwfxDst) && (pwfxSrc->nChannels == pwfxDst->nChannels) + && (pwfxSrc->wFormatTag == WAVE_FORMAT_PCM) && (pwfxDst->wFormatTag == WAVE_FORMAT_MPEGLAYER3) + && (pwfxSrc->wBitsPerSample == 16)) + { + pbeCfg->dwInputSamples = 2048; + pbeCfg->dwOutputSamples = 2048; + pbeCfg->beCfg.dwConfig = BE_CONFIG_MP3; + pbeCfg->beCfg.format.mp3.dwSampleRate = pwfxDst->nSamplesPerSec; // 48000, 44100 and 32000 allowed + pbeCfg->beCfg.format.mp3.byMode = (BYTE)((pwfxSrc->nChannels == 2) ? BE_MP3_MODE_STEREO : BE_MP3_MODE_MONO); + pbeCfg->beCfg.format.mp3.wBitrate = (WORD)(pwfxDst->nAvgBytesPerSec * 8); // 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256 and 320 allowed + pbeCfg->beCfg.format.mp3.bPrivate = FALSE; + pbeCfg->beCfg.format.mp3.bCRC = FALSE; + pbeCfg->beCfg.format.mp3.bCopyright = FALSE; + pbeCfg->beCfg.format.mp3.bOriginal = TRUE; + pbeCfg->hBeStream = NULL; + if (pfnbeInitStream(&pbeCfg->beCfg, &pbeCfg->dwInputSamples, &pbeCfg->dwOutputSamples, &pbeCfg->hBeStream) == BE_ERR_SUCCESSFUL) + { + *phas = (HACMSTREAM)had; + *ppbeCfg = pbeCfg; + pbeCfg->pPCMBuffer = (SHORT *)GlobalAllocPtr(GHND, pbeCfg->dwInputSamples * sizeof(SHORT)); + pbeCfg->dwReadPos = 0; + return MMSYSERR_NOERROR; + } + } + if (pbeCfg) delete pbeCfg; + return MMSYSERR_INVALPARAM; + } + if (m_hACMInst) + { + PFNACMSTREAMOPEN pfnAcmStreamOpen = (PFNACMSTREAMOPEN)GetProcAddress(m_hACMInst, "acmStreamOpen"); + if (pfnAcmStreamOpen) return pfnAcmStreamOpen(phas, had, pwfxSrc, pwfxDst, pwfltr, dwCallback, dwInstance, fdwOpen); + } + return MMSYSERR_INVALPARAM; +} + + +MMRESULT ACMConvert::AcmStreamClose(HACMSTREAM has, DWORD fdwClose) +//----------------------------------------------------------------- +{ + if (((m_hBladeEnc) && (has == (HACMSTREAM)&m_hBladeEnc)) + || ((m_hLameEnc) && (has == (HACMSTREAM)&m_hLameEnc))) + { + HINSTANCE hLib = *(HINSTANCE *)has; + PBLADEENCSTREAMINFO pbeCfg = (has == (HACMSTREAM)&m_hBladeEnc) ? gpbeBladeCfg : gpbeLameCfg; + BECLOSESTREAM pfnbeCloseStream = (BECLOSESTREAM)GetProcAddress(hLib, TEXT_BECLOSESTREAM); + if ((pbeCfg) && (pfnbeCloseStream)) + { + pfnbeCloseStream(pbeCfg->hBeStream); + if (pbeCfg->pPCMBuffer) + { + GlobalFreePtr(pbeCfg->pPCMBuffer); + pbeCfg->pPCMBuffer = NULL; + } + delete pbeCfg; + pbeCfg = NULL; + return MMSYSERR_NOERROR; + } + return MMSYSERR_INVALPARAM; + } + if (m_hACMInst) + { + PFNACMSTREAMCLOSE pfnAcmStreamClose = (PFNACMSTREAMCLOSE)GetProcAddress(m_hACMInst, "acmStreamClose"); + if (pfnAcmStreamClose) return pfnAcmStreamClose(has, fdwClose); + } + return MMSYSERR_INVALPARAM; +} + + +MMRESULT ACMConvert::AcmStreamSize(HACMSTREAM has, DWORD cbInput, LPDWORD pdwOutputBytes, DWORD fdwSize) +//------------------------------------------------------------------------------------------------------ +{ + if (((m_hBladeEnc) && (has == (HACMSTREAM)&m_hBladeEnc)) + || ((m_hLameEnc) && (has == (HACMSTREAM)&m_hLameEnc))) + { + PBLADEENCSTREAMINFO pbeCfg = (has == (HACMSTREAM)&m_hBladeEnc) ? gpbeBladeCfg : gpbeLameCfg; + + if ((pbeCfg) && (pdwOutputBytes)) + { + if (fdwSize & ACM_STREAMSIZEF_DESTINATION) + { + *pdwOutputBytes = pbeCfg->dwOutputSamples * sizeof(short); + } else + if (fdwSize & ACM_STREAMSIZEF_SOURCE) + { + *pdwOutputBytes = pbeCfg->dwInputSamples * sizeof(short); + } + return MMSYSERR_NOERROR; + } + return MMSYSERR_INVALPARAM; + } + if (m_hACMInst) + { + if (fdwSize & ACM_STREAMSIZEF_DESTINATION) // Why does acmStreamSize return ACMERR_NOTPOSSIBLE in this case? + return MMSYSERR_NOERROR; + PFNACMSTREAMSIZE pfnAcmStreamSize = (PFNACMSTREAMSIZE)GetProcAddress(m_hACMInst, "acmStreamSize"); + if (pfnAcmStreamSize) return pfnAcmStreamSize(has, cbInput, pdwOutputBytes, fdwSize); + } + return MMSYSERR_INVALPARAM; +} + + +MMRESULT ACMConvert::AcmStreamPrepareHeader(HACMSTREAM has, LPACMSTREAMHEADER pash, DWORD fdwPrepare) +//--------------------------------------------------------------------------------------------------- +{ + if (((m_hBladeEnc) && (has == (HACMSTREAM)&m_hBladeEnc)) + || ((m_hLameEnc) && (has == (HACMSTREAM)&m_hLameEnc))) + { + pash->fdwStatus = ACMSTREAMHEADER_STATUSF_PREPARED; + return MMSYSERR_NOERROR; + } + if (m_hACMInst) + { + PFNACMSTREAMCONVERT pfnAcmStreamPrepareHeader = (PFNACMSTREAMCONVERT)GetProcAddress(m_hACMInst, "acmStreamPrepareHeader"); + if (pfnAcmStreamPrepareHeader) return pfnAcmStreamPrepareHeader(has, pash, fdwPrepare); + } + return MMSYSERR_INVALPARAM; +} + + +MMRESULT ACMConvert::AcmStreamUnprepareHeader(HACMSTREAM has, LPACMSTREAMHEADER pash, DWORD fdwUnprepare) +//------------------------------------------------------------------------------------------------------- +{ + if (((m_hBladeEnc) && (has == (HACMSTREAM)&m_hBladeEnc)) + || ((m_hLameEnc) && (has == (HACMSTREAM)&m_hLameEnc))) + { + pash->fdwStatus &= ~ACMSTREAMHEADER_STATUSF_PREPARED; + return MMSYSERR_NOERROR; + } + if (m_hACMInst) + { + PFNACMSTREAMCONVERT pfnAcmStreamUnprepareHeader = (PFNACMSTREAMCONVERT)GetProcAddress(m_hACMInst, "acmStreamUnprepareHeader"); + if (pfnAcmStreamUnprepareHeader) return pfnAcmStreamUnprepareHeader(has, pash, fdwUnprepare); + } + return MMSYSERR_INVALPARAM; +} + + +MMRESULT ACMConvert::AcmStreamConvert(HACMSTREAM has, LPACMSTREAMHEADER pash, DWORD fdwConvert) +//--------------------------------------------------------------------------------------------- +{ + static BEENCODECHUNK pfnbeEncodeChunk = NULL; + static BEDEINITSTREAM pfnbeDeinitStream = NULL; + static HINSTANCE hInstEncode = NULL; + + if (((m_hBladeEnc) && (has == (HACMSTREAM)&m_hBladeEnc)) + || ((m_hLameEnc) && (has == (HACMSTREAM)&m_hLameEnc))) + { + PBLADEENCSTREAMINFO pbeCfg = (has == (HACMSTREAM)&m_hBladeEnc) ? gpbeBladeCfg : gpbeLameCfg; + HINSTANCE hLib = *(HINSTANCE *)has; + + if (hInstEncode != hLib) + { + pfnbeEncodeChunk = (BEENCODECHUNK)GetProcAddress(hLib, TEXT_BEENCODECHUNK); + pfnbeDeinitStream = (BEDEINITSTREAM)GetProcAddress(hLib, TEXT_BEDEINITSTREAM); + hInstEncode = hLib; + } + pash->fdwStatus |= ACMSTREAMHEADER_STATUSF_DONE; + if (fdwConvert & ACM_STREAMCONVERTF_END) + { + if ((pfnbeDeinitStream) && (pbeCfg)) + { + pfnbeDeinitStream(pbeCfg->hBeStream, pash->pbDst, &pash->cbDstLengthUsed); + return MMSYSERR_NOERROR; + } + } else + { + if ((pfnbeEncodeChunk) && (pbeCfg)) + { + DWORD dwBytesLeft = pbeCfg->dwInputSamples*2 - pbeCfg->dwReadPos; + if (!dwBytesLeft) + { + dwBytesLeft = pbeCfg->dwInputSamples*2; + pbeCfg->dwReadPos = 0; + } + if (dwBytesLeft > pash->cbSrcLength) dwBytesLeft = pash->cbSrcLength; + memcpy(&pbeCfg->pPCMBuffer[pbeCfg->dwReadPos/2], pash->pbSrc, dwBytesLeft); + pbeCfg->dwReadPos += dwBytesLeft; + pash->cbSrcLengthUsed = dwBytesLeft; + pash->cbDstLengthUsed = 0; + if (pbeCfg->dwReadPos == pbeCfg->dwInputSamples*2) + { + if (pfnbeEncodeChunk(pbeCfg->hBeStream, pbeCfg->dwInputSamples, pbeCfg->pPCMBuffer, pash->pbDst, &pash->cbDstLengthUsed) != 0) return MMSYSERR_INVALPARAM; + pbeCfg->dwReadPos = 0; + } + return MMSYSERR_NOERROR; + } + } + return MMSYSERR_INVALPARAM; + } + if (m_hACMInst) + { + PFNACMSTREAMCONVERT pfnAcmStreamConvert = (PFNACMSTREAMCONVERT)GetProcAddress(m_hACMInst, "acmStreamConvert"); + if (pfnAcmStreamConvert) return pfnAcmStreamConvert(has, pash, fdwConvert); + } + return MMSYSERR_INVALPARAM; +} Added: trunk/OpenMPT/mptrack/ACMConvert.h =================================================================== --- trunk/OpenMPT/mptrack/ACMConvert.h (rev 0) +++ trunk/OpenMPT/mptrack/ACMConvert.h 2011-08-22 18:21:40 UTC (rev 993) @@ -0,0 +1,69 @@ +/* + * + * ACMConvert.h + * ------------ + * Purpose: Header for ACM and MPEG Layer-3 conversion + * Notes : (currently none) + * Authors: Olivier Lapicque + * OpenMPT Devs + * + */ + + +#pragma once +#ifndef ACMCONVERT_H +#define ACMCONVERT_H + +///////////////////////////////////////////////////////////////////////////// +// ACM Functions (for dynamic linking) + +typedef VOID (ACMAPI *PFNACMMETRICS)(HACMOBJ, UINT, LPVOID); +typedef MMRESULT (ACMAPI *PFNACMFORMATENUM)(HACMDRIVER, LPACMFORMATDETAILSA, ACMFORMATENUMCBA, DWORD dwInstance, DWORD fdwEnum); +typedef MMRESULT (ACMAPI *PFNACMDRIVEROPEN)(LPHACMDRIVER, HACMDRIVERID, DWORD); +typedef MMRESULT (ACMAPI *PFNACMDRIVERCLOSE)(HACMDRIVER, DWORD); +typedef MMRESULT (ACMAPI *PFNACMSTREAMOPEN)(LPHACMSTREAM, HACMDRIVER, LPWAVEFORMATEX, LPWAVEFORMATEX, LPWAVEFILTER, DWORD, DWORD, DWORD); +typedef MMRESULT (ACMAPI *PFNACMSTREAMCLOSE)(HACMSTREAM, DWORD); +typedef MMRESULT (ACMAPI *PFNACMSTREAMSIZE)(HACMSTREAM, DWORD, LPDWORD, DWORD); +typedef MMRESULT (ACMAPI *PFNACMSTREAMCONVERT)(HACMSTREAM, LPACMSTREAMHEADER, DWORD); +typedef MMRESULT (ACMAPI *PFNACMDRIVERDETAILS)(HACMDRIVERID, LPACMDRIVERDETAILS, DWORD); + + +//============== +class ACMConvert +//============== +{ +protected: + HINSTANCE m_hACMInst; + HINSTANCE m_hBladeEnc, m_hLameEnc; + PFNACMFORMATENUM m_pfnAcmFormatEnum; + static BOOL layer3Present; + +public: + BOOL InitializeACM(BOOL bNoAcm = FALSE); + BOOL UninitializeACM(); + static void AcmExceptionHandler(); + MMRESULT AcmFormatEnum(HACMDRIVER had, LPACMFORMATDETAILSA pafd, ACMFORMATENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum); + MMRESULT AcmDriverOpen(LPHACMDRIVER, HACMDRIVERID, DWORD); + MMRESULT AcmDriverDetails(HACMDRIVERID hadid, LPACMDRIVERDETAILS padd, DWORD fdwDetails); + MMRESULT AcmDriverClose(HACMDRIVER, DWORD); + MMRESULT AcmStreamOpen(LPHACMSTREAM, HACMDRIVER, LPWAVEFORMATEX, LPWAVEFORMATEX, LPWAVEFILTER pwfltr, DWORD dwCallback, DWORD dwInstance, DWORD fdwOpen); + MMRESULT AcmStreamClose(HACMSTREAM, DWORD); + MMRESULT AcmStreamSize(HACMSTREAM has, DWORD cbInput, LPDWORD pdwOutputBytes, DWORD fdwSize); + MMRESULT AcmStreamPrepareHeader(HACMSTREAM has, LPACMSTREAMHEADER pash, DWORD fdwPrepare); + MMRESULT AcmStreamUnprepareHeader(HACMSTREAM has, LPACMSTREAMHEADER pash, DWORD fdwUnprepare); + MMRESULT AcmStreamConvert(HACMSTREAM has, LPACMSTREAMHEADER pash, DWORD fdwConvert); + BOOL IsLayer3Present() const { return layer3Present; }; + + ACMConvert() + { + m_hBladeEnc = NULL; + m_hLameEnc = NULL; + m_hACMInst = NULL; + } + +protected: + static BOOL CALLBACK AcmFormatEnumCB(HACMDRIVERID, LPACMFORMATDETAILS, DWORD, DWORD); + +}; + +#endif // ACMCONVERT_H Modified: trunk/OpenMPT/mptrack/Mod2wave.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mod2wave.cpp 2011-08-22 14:14:03 UTC (rev 992) +++ trunk/OpenMPT/mptrack/Mod2wave.cpp 2011-08-22 18:21:40 UTC (rev 993) @@ -371,7 +371,7 @@ pwfx->wBitsPerSample = 16; pwfx->nBlockAlign = (pwfx->nChannels * pwfx->wBitsPerSample) / 8; pwfx->nAvgBytesPerSec = pwfx->nSamplesPerSec * pwfx->nBlockAlign; - theApp.AcmFormatEnum(NULL, &afd, AcmFormatEnumCB, (DWORD)this, ACM_FORMATENUMF_CONVERT); + theApp.GetACMConvert().AcmFormatEnum(NULL, &afd, AcmFormatEnumCB, (DWORD)this, ACM_FORMATENUMF_CONVERT); m_bDriversEnumerated = TRUE; m_CbnDriver.SetCurSel(m_nDriverIndex); if (m_bSaveInfoField) CheckDlgButton(IDC_CHECK3, MF_CHECKED); @@ -413,7 +413,7 @@ pwfx->wBitsPerSample = 16; pwfx->nBlockAlign = pwfx->nChannels * pwfx->wBitsPerSample / 8; pwfx->nAvgBytesPerSec = pwfx->nSamplesPerSec * pwfx->nBlockAlign; - theApp.AcmFormatEnum(NULL, &afd, AcmFormatEnumCB, (DWORD)this, ACM_FORMATENUMF_CONVERT); + theApp.GetACMConvert().AcmFormatEnum(NULL, &afd, AcmFormatEnumCB, (DWORD)this, ACM_FORMATENUMF_CONVERT); m_CbnFormat.SetCurSel(m_nFormatIndex); } @@ -454,7 +454,7 @@ } MemsetZero(add); add.cbStruct = sizeof(add); - if (theApp.AcmDriverDetails(hdid, &add, 0L) == MMSYSERR_NOERROR) + if (theApp.GetACMConvert().AcmDriverDetails(hdid, &add, 0L) == MMSYSERR_NOERROR) { Drivers[m_nNumDrivers] = hdid; CHAR *pszName = ((add.szLongName[0]) && (strlen(add.szLongName) < 40)) ? add.szLongName : add.szShortName; @@ -978,12 +978,12 @@ wfxSrc.cbSize = 0; dwDstBufSize = WAVECONVERTBUFSIZE; // Open the ACM Driver - if (theApp.AcmDriverOpen(&hADriver, m_hadid, 0L) != MMSYSERR_NOERROR) goto OnError; - if (theApp.AcmStreamOpen(&hAStream, hADriver, &wfxSrc, m_pwfx, NULL, 0L, 0L, ACM_STREAMOPENF_NONREALTIME) != MMSYSERR_NOERROR) goto OnError; + if (theApp.GetACMConvert().AcmDriverOpen(&hADriver, m_hadid, 0L) != MMSYSERR_NOERROR) goto OnError; + if (theApp.GetACMConvert().AcmStreamOpen(&hAStream, hADriver, &wfxSrc, m_pwfx, NULL, 0L, 0L, ACM_STREAMOPENF_NONREALTIME) != MMSYSERR_NOERROR) goto OnError; // This call is useless for BLADEenc/LAMEenc, but required for ACM codecs! - if (theApp.AcmStreamSize(hAStream, WAVECONVERTBUFSIZE, &dwDstBufSize, ACM_STREAMSIZEF_SOURCE) != MMSYSERR_NOERROR) goto OnError; + if (theApp.GetACMConvert().AcmStreamSize(hAStream, WAVECONVERTBUFSIZE, &dwDstBufSize, ACM_STREAMSIZEF_SOURCE) != MMSYSERR_NOERROR) goto OnError; // This call is useless for ACM, but required for BLADEenc/LAMEenc codecs! - if (theApp.AcmStreamSize(hAStream, WAVECONVERTBUFSIZE, &dwDstBufSize, ACM_STREAMSIZEF_DESTINATION) != MMSYSERR_NOERROR) goto OnError; + if (theApp.GetACMConvert().AcmStreamSize(hAStream, WAVECONVERTBUFSIZE, &dwDstBufSize, ACM_STREAMSIZEF_DESTINATION) != MMSYSERR_NOERROR) goto OnError; //if (dwDstBufSize > 0x10000) dwDstBufSize = 0x10000; pcmBuffer = new BYTE[WAVECONVERTBUFSIZE]; dstBuffer = new BYTE[dwDstBufSize]; @@ -996,7 +996,7 @@ ash.cbSrcLength = WAVECONVERTBUFSIZE; ash.pbDst = dstBuffer; ash.cbDstLength = dwDstBufSize; - if (theApp.AcmStreamPrepareHeader(hAStream, &ash, 0L) != MMSYSERR_NOERROR) goto OnError; + if (theApp.GetACMConvert().AcmStreamPrepareHeader(hAStream, &ash, 0L) != MMSYSERR_NOERROR) goto OnError; bPrepared = true; // Creating the output file if ((f = fopen(m_lpszFileName, "wb")) == NULL) @@ -1080,7 +1080,7 @@ ullSamples += lRead; ash.cbSrcLength = lRead * wfxSrc.nBlockAlign + WAVECONVERTBUFSIZE - pcmBufSize; ash.cbDstLengthUsed = 0; - if (theApp.AcmStreamConvert(hAStream, &ash, (lRead) ? ACM_STREAMCONVERTF_BLOCKALIGN : ACM_STREAMCONVERTF_END) != MMSYSERR_NOERROR) break; + if (theApp.GetACMConvert().AcmStreamConvert(hAStream, &ash, (lRead) ? ACM_STREAMCONVERTF_BLOCKALIGN : ACM_STREAMCONVERTF_END) != MMSYSERR_NOERROR) break; do { if (::PeekMessage(&msg, m_hWnd, 0, 0, PM_REMOVE)) @@ -1152,9 +1152,9 @@ fclose(f); if (!m_bAbort) retval = IDOK; OnError: - if (bPrepared) theApp.AcmStreamUnprepareHeader(hAStream, &ash, 0L); - if (hAStream != NULL) theApp.AcmStreamClose(hAStream, 0L); - if (hADriver != NULL) theApp.AcmDriverClose(hADriver, 0L); + if (bPrepared) theApp.GetACMConvert().AcmStreamUnprepareHeader(hAStream, &ash, 0L); + if (hAStream != NULL) theApp.GetACMConvert().AcmStreamClose(hAStream, 0L); + if (hADriver != NULL) theApp.GetACMConvert().AcmDriverClose(hADriver, 0L); if (pcmBuffer) delete[] pcmBuffer; if (dstBuffer) delete[] dstBuffer; //rewbs: reduce to normal priority during debug for easier hang debugging Modified: trunk/OpenMPT/mptrack/Mptrack.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.cpp 2011-08-22 14:14:03 UTC (rev 992) +++ trunk/OpenMPT/mptrack/Mptrack.cpp 2011-08-22 18:21:40 UTC (rev 993) @@ -1,4 +1,3 @@ -MB_ICONERROR // mptrack.cpp : Defines the class behaviors for the application. // @@ -13,14 +12,13 @@ #include "vstplug.h" #include "CreditStatic.h" #include "hyperEdit.h" -#include "bladedll.h" #include "commctrl.h" #include "version.h" #include "test/test.h" -#include <shlwapi.h> #include <afxadv.h> #include "UpdateCheck.h" #include "../soundlib/StringFixer.h" +#include "dbghelp.h" // rewbs.memLeak #define _CRTDBG_MAP_ALLOC @@ -596,12 +594,8 @@ m_pModTemplate = NULL; m_pPluginManager = NULL; m_bInitialized = FALSE; - m_bLayer3Present = FALSE; m_bExWaveSupport = FALSE; m_bDebugMode = FALSE; - m_hBladeEnc = NULL; - m_hLameEnc = NULL; - m_hACMInst = NULL; m_hAlternateResourceHandle = NULL; m_szConfigFileName[0] = 0; for (UINT i=0; i<MAX_DLS_BANKS; i++) gpDLSBanks[i] = NULL; @@ -645,17 +639,6 @@ ///////////////////////////////////////////////////////////////////////////// // CTrackApp initialization -void Terminate_AppThread() -//---------------------------------------------- -{ - //TODO: Why does this not get called. - AfxMessageBox("Application thread terminated unexpectedly. Attempting to shut down audio device"); - CMainFrame* pMainFrame = CMainFrame::GetMainFrame(); - if (pMainFrame->gpSoundDevice) pMainFrame->gpSoundDevice->Reset(); - pMainFrame->audioCloseDevice(); - exit(-1); -} - #ifdef WIN32 // Legacy stuff // Move a config file called sFileName from the App's directory (or one of its sub directories specified by sSubDir) to // %APPDATA%. If specified, it will be renamed to sNewFileName. Existing files are never overwritten. @@ -802,8 +785,6 @@ //---------------------------- { - set_terminate(Terminate_AppThread); - // Initialize OLE MFC support AfxOleInit(); // Standard initialization @@ -906,7 +887,7 @@ // Initialize ACM Support if (GetProfileInt("Settings", "DisableACM", 0)) cmdInfo.m_bNoAcm = true; - if (!cmdInfo.m_bNoMp3) InitializeACM(cmdInfo.m_bNoAcm); + if (!cmdInfo.m_bNoMp3) GetACMConvert().InitializeACM(cmdInfo.m_bNoAcm); // Initialize DXPlugins if (!cmdInfo.m_bNoPlugins) InitializeDXPlugins(); @@ -987,7 +968,7 @@ UninitializeDXPlugins(); // Uninitialize ACM - UninitializeACM(); + GetACMConvert().UninitializeACM(); return CWinApp::ExitInstance(); } @@ -2294,534 +2275,6 @@ } -///////////////////////////////////////////////////////////////////////////////////////// -// MPEG Layer-3 Functions (through ACM - access to LAMEenc and BLADEenc is emulated through the ACM interface) - -typedef struct BLADEENCSTREAMINFO -{ - BE_CONFIG beCfg; - LONGLONG dummy; - DWORD dwInputSamples; - DWORD dwOutputSamples; - HBE_STREAM hBeStream; - SHORT *pPCMBuffer; - DWORD dwReadPos; -} BLADEENCSTREAMINFO, *PBLADEENCSTREAMINFO; - -static PBLADEENCSTREAMINFO gpbeBladeCfg = NULL; -static PBLADEENCSTREAMINFO gpbeLameCfg = NULL; - -#define TRAP_ACM_FAULTS - -#ifdef TRAP_ACM_FAULTS -void CTrackApp::AcmExceptionHandler() -{ - theApp.m_hACMInst = NULL; - theApp.WriteProfileInt("Settings", "DisableACM", 1); -} -#endif - -BOOL CTrackApp::InitializeACM(BOOL bNoAcm) -//---------------------------------------- -{ - DWORD (ACMAPI *pfnAcmGetVersion)(void); - DWORD dwVersion; - UINT fuErrorMode; - BOOL bOk = FALSE; - - fuErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX); - try { - m_hBladeEnc = LoadLibrary(TEXT("BLADEENC.DLL")); - m_hLameEnc = LoadLibrary(TEXT("LAME_ENC.DLL")); - } catch(...) {} - if (!bNoAcm) - { - #ifdef TRAP_ACM_FAULTS - try { - #endif - m_hACMInst = LoadLibrary(TEXT("MSACM32.DLL")); - #ifdef TRAP_ACM_FAULTS - } catch(...) {} - #endif - } - SetErrorMode(fuErrorMode); - if (m_hBladeEnc != NULL) - { - BEVERSION pfnBeVersion = (BEVERSION)GetProcAddress(m_hBladeEnc, TEXT_BEVERSION); - if (!pfnBeVersion) - { - FreeLibrary(m_hBladeEnc); - m_hBladeEnc = NULL; - } else - { - m_bLayer3Present = TRUE; - bOk = TRUE; - } - } - if (m_hLameEnc != NULL) - { - BEVERSION pfnBeVersion = (BEVERSION)GetProcAddress(m_hLameEnc, TEXT_BEVERSION); - if (!pfnBeVersion) - { - FreeLibrary(m_hLameEnc); - m_hLameEnc = NULL; - } else - { - m_bLayer3Present = TRUE; - bOk = TRUE; - } - } - if ((m_hACMInst < (HINSTANCE)HINSTANCE_ERROR) || (!m_hACMInst)) - { - m_hACMInst = NULL; - return bOk; - } -#ifdef TRAP_ACM_FAULTS - try { -#endif - *(FARPROC *)&pfnAcmGetVersion = GetProcAddress(m_hACMInst, "acmGetVersion"); - dwVersion = 0; - if (pfnAcmGetVersion) dwVersion = pfnAcmGetVersion(); - if (HIWORD(dwVersion) < 0x0200) - { - FreeLibrary(m_hACMInst); - m_hACMInst = NULL; - return bOk; - } - // Load Function Pointers - m_pfnAcmFormatEnum = (PFNACMFORMATENUM)GetProcAddress(m_hACMInst, "acmFormatEnumA"); - // Enumerate formats - if (m_pfnAcmFormatEnum) - { - ACMFORMATDETAILS afd; - BYTE wfx[256]; - WAVEFORMATEX *pwfx = (WAVEFORMATEX *)&wfx; - - MemsetZero(afd); - MemsetZero(*pwfx); - afd.cbStruct = sizeof(ACMFORMATDETAILS); - afd.dwFormatTag = WAVE_FORMAT_PCM; - afd.pwfx = pwfx; - afd.cbwfx = sizeof(wfx); - pwfx->wFormatTag = WAVE_FORMAT_PCM; - pwfx->nChannels = 2; - pwfx->nSamplesPerSec = 44100; - pwfx->wBitsPerSample = 16; - pwfx->nBlockAlign = (WORD)((pwfx->nChannels * pwfx->wBitsPerSample) / 8); - pwfx->nAvgBytesPerSec = pwfx->nSamplesPerSec * pwfx->nBlockAlign; - m_pfnAcmFormatEnum(NULL, &afd, AcmFormatEnumCB, NULL, ACM_FORMATENUMF_CONVERT); - } -#ifdef TRAP_ACM_FAULTS - } catch(...){} -#endif - return TRUE; -} - - -BOOL CTrackApp::UninitializeACM() -//------------------------------- -{ - if (m_hACMInst) - { - FreeLibrary(m_hACMInst); - m_hACMInst = NULL; - } - if (m_hLameEnc) - { - FreeLibrary(m_hLameEnc); - m_hLameEnc = NULL; - } - if (m_hBladeEnc) - { - FreeLibrary(m_hBladeEnc); - m_hBladeEnc = NULL; - } - return TRUE; -} - - -MMRESULT CTrackApp::AcmFormatEnum(HACMDRIVER had, LPACMFORMATDETAILSA pafd, ACMFORMATENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum) -//--------------------------------------------------------------------------------------------------------------------------------------- -{ - MMRESULT err = MMSYSERR_INVALPARAM; - if ((m_hBladeEnc) || (m_hLameEnc)) - { - HACMDRIVER hBlade = (HACMDRIVER)&m_hBladeEnc; - HACMDRIVER hLame = (HACMDRIVER)&m_hLameEnc; - if (((had == hBlade) || (had == hLame) || (had == NULL)) && (pafd) && (fnCallback) - && (fdwEnum & ACM_FORMATENUMF_CONVERT) && (pafd->dwFormatTag == WAVE_FORMAT_PCM)) - { - ACMFORMATDETAILS afd; - MPEGLAYER3WAVEFORMAT wfx; - - afd.dwFormatIndex = 0; - for (UINT iFmt=0; iFmt<0x40; iFmt++) - { - afd.cbStruct = sizeof(afd); - afd.dwFormatTag = WAVE_FORMAT_MPEGLAYER3; - afd.fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC; - afd.pwfx = (LPWAVEFORMATEX)&wfx; - afd.cbwfx = sizeof(wfx); - wfx.wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3; - wfx.wfx.nChannels = (WORD)((iFmt & 0x20) ? 1 : 2); - wfx.wfx.nSamplesPerSec = 0; - wfx.wfx.nBlockAlign = 1; - wfx.wfx.wBitsPerSample = 0; - wfx.wfx.cbSize = MPEGLAYER3_WFX_EXTRA_BYTES; - wfx.wID = MPEGLAYER3_ID_MPEG; - wfx.fdwFlags = MPEGLAYER3_FLAG_PADDING_ISO; - wfx.nBlockSize = 384; - wfx.nFramesPerBlock = 1; - wfx.nCodecDelay = 1000; - switch((iFmt >> 3) & 0x03) - { - case 0x00: wfx.wfx.nSamplesPerSec = 48000; break; - case 0x01: wfx.wfx.nSamplesPerSec = 44100; break; - case 0x02: wfx.wfx.nSamplesPerSec = 32000; break; - } - switch(iFmt & 7) - { - case 5: wfx.wfx.nAvgBytesPerSec = 320/8; break; - case 4: wfx.wfx.nAvgBytesPerSec = 64/8; break; - case 3: wfx.wfx.nAvgBytesPerSec = 96/8; break; - case 2: wfx.wfx.nAvgBytesPerSec = 128/8; break; - case 1: if (wfx.wfx.nChannels == 2) { wfx.wfx.nAvgBytesPerSec = 192/8; break; } - case 0: if (wfx.wfx.nChannels == 2) { wfx.wfx.nAvgBytesPerSec = 256/8; break; } - default: wfx.wfx.nSamplesPerSec = 0; - } - wsprintf(afd.szFormat, "%dkbps, %dHz, %s", wfx.wfx.nAvgBytesPerSec*8, wfx.wfx.nSamplesPerSec, (wfx.wfx.nChannels == 2) ? "stereo" : "mono"); - if (wfx.wfx.nSamplesPerSec) - { - if (m_hBladeEnc) fnCallback((HACMDRIVERID)hBlade, &afd, dwInstance, ACMDRIVERDETAILS_SUPPORTF_CODEC); - if (m_hLameEnc) fnCallback((HACMDRIVERID)hLame, &afd, dwInstance, ACMDRIVERDETAILS_SUPPORTF_CODEC); - afd.dwFormatIndex++; - } - } - err = MMSYSERR_NOERROR; - } - } - if (m_pfnAcmFormatEnum) - { - err = m_pfnAcmFormatEnum(had, pafd, fnCallback, dwInstance, fdwEnum); - } - return err; -} - - -BOOL CTrackApp::AcmFormatEnumCB(HACMDRIVERID, LPACMFORMATDETAILS pafd, DWORD, DWORD fdwSupport) -//--------------------------------------------------------------------------------------------- -{ - if ((pafd) && (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC)) - { - if (pafd->dwFormatTag == WAVE_FORMAT_MPEGLAYER3) theApp.m_bLayer3Present = TRUE; - } - return TRUE; -} - - -MMRESULT CTrackApp::AcmDriverOpen(LPHACMDRIVER phad, HACMDRIVERID hadid, DWORD fdwOpen) -//------------------------------------------------------------------------------------- -{ - if ((m_hBladeEnc) && (hadid == (HACMDRIVERID)&m_hBladeEnc)) - { - *phad = (HACMDRIVER)&m_hBladeEnc; - return MMSYSERR_NOERROR; - } - if ((m_hLameEnc) && (hadid == (HACMDRIVERID)&m_hLameEnc)) - { - *phad = (HACMDRIVER)&m_hLameEnc; - return MMSYSERR_NOERROR; - } - if (m_hACMInst) - { - PFNACMDRIVEROPEN pfnAcmDriverOpen = (PFNACMDRIVEROPEN)GetProcAddress(m_hACMInst, "acmDriverOpen"); - if (pfnAcmDriverOpen) return pfnAcmDriverOpen(phad, hadid, fdwOpen); - } - return MMSYSERR_INVALPARAM; -} - - -MMRESULT CTrackApp::AcmDriverClose(HACMDRIVER had, DWORD fdwClose) -//---------------------------------------------------------------- -{ - if ((m_hBladeEnc) && (had == (HACMDRIVER)&m_hBladeEnc)) - { - return MMSYSERR_NOERROR; - } - if ((m_hLameEnc) && (had == (HACMDRIVER)&m_hLameEnc)) - { - return MMSYSERR_NOERROR; - } - if (m_hACMInst) - { - PFNACMDRIVERCLOSE pfnAcmDriverClose = (PFNACMDRIVERCLOSE)GetProcAddress(m_hACMInst, "acmDriverClose"); - if (pfnAcmDriverClose) return pfnAcmDriverClose(had, fdwClose); - } - return MMSYSERR_INVALPARAM; -} - - -MMRESULT CTrackApp::AcmDriverDetails(HACMDRIVERID hadid, LPACMDRIVERDETAILS padd, DWORD fdwDetails) -//------------------------------------------------------------------------------------------------- -{ - if (((m_hBladeEnc) && (hadid == (HACMDRIVERID)(&m_hBladeEnc))) - || ((m_hLameEnc) && (hadid == (HACMDRIVERID)(&m_hLameEnc)))) - { - if (!padd) return MMSYSERR_INVALPARAM; - padd->cbStruct = sizeof(ACMDRIVERDETAILS); - padd->fccType = ACMDRIVERDETAILS_FCCTYPE_AUDIOCODEC; - padd->fccComp = ACMDRIVERDETAILS_FCCCOMP_UNDEFINED; - padd->wMid = 0; - padd->wPid = 0; - padd->vdwACM = 0x04020000; - padd->vdwDriver = 0x04020000; - padd->fdwSupport = ACMDRIVERDETAILS_SUPPORTF_CODEC; - padd->cFormatTags = 1; - padd->cFilterTags = 0; - padd->hicon = NULL; - strcpy(padd->szShortName, (hadid == (HACMDRIVERID)(&m_hBladeEnc)) ? "BladeEnc MP3" : "LAME Encoder"); - strcpy(padd->szLongName, padd->szShortName); - padd->szCopyright[0] = 0; - padd->szLicensing[0] = 0; - padd->szFeatures[0] = 0; - return MMSYSERR_NOERROR; - } - if (m_hACMInst) - { - PFNACMDRIVERDETAILS pfnAcmDriverDetails = (PFNACMDRIVERDETAILS)GetProcAddress(m_hACMInst, "acmDriverDetailsA"); - if (pfnAcmDriverDetails) return pfnAcmDriverDetails(hadid, padd, fdwDetails); - } - return MMSYSERR_INVALPARAM; -} - - -MMRESULT CTrackApp::AcmStreamOpen( - LPHACMSTREAM phas, // pointer to stream handle - HACMDRIVER had, // optional driver handle - LPWAVEFORMATEX pwfxSrc, // source format to convert - LPWAVEFORMATEX pwfxDst, // required destination format - LPWAVEFILTER pwfltr, // optional filter - DWORD dwCallback, // callback - DWORD dwInstance, // callback instance data - DWORD fdwOpen) // ACM_STREAMOPENF_* and CALLBACK_* -//------------------------------------------------------------------------- -{ - PBLADEENCSTREAMINFO *ppbeCfg = NULL; - HINSTANCE hLib = NULL; - - if ((m_hBladeEnc) && (had == (HACMDRIVER)&m_hBladeEnc)) - { - ppbeCfg = &gpbeBladeCfg; - hLib = m_hBladeEnc; - } - if ((m_hLameEnc) && (had == (HACMDRIVER)&m_hLameEnc)) - { - ppbeCfg = &gpbeLameCfg; - hLib = m_hLameEnc; - } - if ((ppbeCfg) && (hLib)) - { - BEINITSTREAM pfnbeInitStream = (BEINITSTREAM)GetProcAddress(hLib, TEXT_BEINITSTREAM); - if (!pfnbeInitStream) return MMSYSERR_INVALPARAM; - PBLADEENCSTREAMINFO pbeCfg = new BLADEENCSTREAMINFO; - if ((pbeCfg) && (pwfxSrc) && (pwfxDst) && (pwfxSrc->nChannels == pwfxDst->nChannels) - && (pwfxSrc->wFormatTag == WAVE_FORMAT_PCM) && (pwfxDst->wFormatTag == WAVE_FORMAT_MPEGLAYER3) - && (pwfxSrc->wBitsPerSample == 16)) - { - pbeCfg->dwInputSamples = 2048; - pbeCfg->dwOutputSamples = 2048; - pbeCfg->beCfg.dwConfig = BE_CONFIG_MP3; - pbeCfg->beCfg.format.mp3.dwSampleRate = pwfxDst->nSamplesPerSec; // 48000, 44100 and 32000 allowed - pbeCfg->beCfg.format.mp3.byMode = (BYTE)((pwfxSrc->nChannels == 2) ? BE_MP3_MODE_STEREO : BE_MP3_MODE_MONO); - pbeCfg->beCfg.format.mp3.wBitrate = (WORD)(pwfxDst->nAvgBytesPerSec * 8); // 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256 and 320 allowed - pbeCfg->beCfg.format.mp3.bPrivate = FALSE; - pbeCfg->beCfg.format.mp3.bCRC = FALSE; - pbeCfg->beCfg.format.mp3.bCopyright = FALSE; - pbeCfg->beCfg.format.mp3.bOriginal = TRUE; - pbeCfg->hBeStream = NULL; - if (pfnbeInitStream(&pbeCfg->beCfg, &pbeCfg->dwInputSamples, &pbeCfg->dwOutputSamples, &pbeCfg->hBeStream) == BE_ERR_SUCCESSFUL) - { - *phas = (HACMSTREAM)had; - *ppbeCfg = pbeCfg; - pbeCfg->pPCMBuffer = (SHORT *)GlobalAllocPtr(GHND, pbeCfg->dwInputSamples * sizeof(SHORT)); - pbeCfg->dwReadPos = 0; - return MMSYSERR_NOERROR; - } - } - if (pbeCfg) delete pbeCfg; - return MMSYSERR_INVALPARAM; - } - if (m_hACMInst) - { - PFNACMSTREAMOPEN pfnAcmStreamOpen = (PFNACMSTREAMOPEN)GetProcAddress(m_hACMInst, "acmStreamOpen"); - if (pfnAcmStreamOpen) return pfnAcmStreamOpen(phas, had, pwfxSrc, pwfxDst, pwfltr, dwCallback, dwInstance, fdwOpen); - } - return MMSYSERR_INVALPARAM; -} - - -MMRESULT CTrackApp::AcmStreamClose(HACMSTREAM has, DWORD fdwClose) -//---------------------------------------------------------------- -{ - if (((m_hBladeEnc) && (has == (HACMSTREAM)&m_hBladeEnc)) - || ((m_hLameEnc) && (has == (HACMSTREAM)&m_hLameEnc))) - { - HINSTANCE hLib = *(HINSTANCE *)has; - PBLADEENCSTREAMINFO pbeCfg = (has == (HACMSTREAM)&m_hBladeEnc) ? gpbeBladeCfg : gpbeLameCfg; - BECLOSESTREAM pfnbeCloseStream = (BECLOSESTREAM)GetProcAddress(hLib, TEXT_BECLOSESTREAM); - if ((pbeCfg) && (pfnbeCloseStream)) - { - pfnbeCloseStream(pbeCfg->hBeStream); - if (pbeCfg->pPCMBuffer) - { - GlobalFreePtr(pbeCfg->pPCMBuffer); - pbeCfg->pPCMBuffer = NULL; - } - delete pbeCfg; - pbeCfg = NULL; - return MMSYSERR_NOERROR; - } - return MMSYSERR_INVALPARAM; - } - if (m_hACMInst) - { - PFNACMSTREAMCLOSE pfnAcmStreamClose = (PFNACMSTREAMCLOSE)GetProcAddress(m_hACMInst, "acmStreamClose"); - if (pfnAcmStreamClose) return pfnAcmStreamClose(has, fdwClose); - } - return MMSYSERR_INVALPARAM; -} - - -MMRESULT CTrackApp::AcmStreamSize(HACMSTREAM has, DWORD cbInput, LPDWORD pdwOutputBytes, DWORD fdwSize) -//----------------------------------------------------------------------------------------------------- -{ - if (((m_hBladeEnc) && (has == (HACMSTREAM)&m_hBladeEnc)) - || ((m_hLameEnc) && (has == (HACMSTREAM)&m_hLameEnc))) - { - PBLADEENCSTREAMINFO pbeCfg = (has == (HACMSTREAM)&m_hBladeEnc) ? gpbeBladeCfg : gpbeLameCfg; - - if ((pbeCfg) && (pdwOutputBytes)) - { - if (fdwSize & ACM_STREAMSIZEF_DESTINATION) - { - *pdwOutputBytes = pbeCfg->dwOutputSamples * sizeof(short); - } else - if (fdwSize & ACM_STREAMSIZEF_SOURCE) - { - *pdwOutputBytes = pbeCfg->dwInputSamples * sizeof(short); - } - return MMSYSERR_NOERROR; - } - return MMSYSERR_INVALPARAM; - } - if (m_hACMInst) - { - if (fdwSize & ACM_STREAMSIZEF_DESTINATION) // Why does acmStreamSize return ACMERR_NOTPOSSIBLE in this case? - return MMSYSERR_NOERROR; - PFNACMSTREAMSIZE pfnAcmStreamSize = (PFNACMSTREAMSIZE)GetProcAddress(m_hACMInst, "acmStreamSize"); - if (pfnAcmStreamSize) return pfnAcmStreamSize(has, cbInput, pdwOutputBytes, fdwSize); - } - return MMSYSERR_INVALPARAM; -} - - -MMRESULT CTrackApp::AcmStreamPrepareHeader(HACMSTREAM has, LPACMSTREAMHEADER pash, DWORD fdwPrepare) -//-------------------------------------------------------------------------------------------------- -{ - if (((m_hBladeEnc) && (has == (HACMSTREAM)&m_hBladeEnc)) - || ((m_hLameEnc) && (has == (HACMSTREAM)&m_hLameEnc))) - { - pash->fdwStatus = ACMSTREAMHEADER_STATUSF_PREPARED; - return MMSYSERR_NOERROR; - } - if (m_hACMInst) - { - PFNACMSTREAMCONVERT pfnAcmStreamPrepareHeader = (PFNACMSTREAMCONVERT)GetProcAddress(m_hACMInst, "acmStreamPrepareHeader"); - if (pfnAcmStreamPrepareHeader) return pfnAcmStreamPrepareHeader(has, pash, fdwPrepare); - } - return MMSYSERR_INVALPARAM; -} - - -MMRESULT CTrackApp::AcmStreamUnprepareHeader(HACMSTREAM has, LPACMSTREAMHEADER pash, DWORD fdwUnprepare) -//------------------------------------------------------------------------------------------------------ -{ - if (((m_hBladeEnc) && (has == (HACMSTREAM)&m_hBladeEnc)) - || ((m_hLameEnc) && (has == (HACMSTREAM)&m_hLameEnc))) - { - pash->fdwStatus &= ~ACMSTREAMHEADER_STATUSF_PREPARED; - return MMSYSERR_NOERROR; - } - if (m_hACMInst) - { - PFNACMSTREAMCONVERT pfnAcmStreamUnprepareHeader = (PFNACMSTREAMCONVERT)GetProcAddress(m_hACMInst, "acmStreamUnprepareHeader"); - if (pfnAcmStreamUnprepareHeader) return pfnAcmStreamUnprepareHeader(has, pash, fdwUnprepare); - } - return MMSYSERR_INVALPARAM; -} - - -MMRESULT CTrackApp::AcmStreamConvert(HACMSTREAM has, LPACMSTREAMHEADER pash, DWORD fdwConvert) -//-------------------------------------------------------------------------------------------- -{ - static BEENCODECHUNK pfnbeEncodeChunk = NULL; - static BEDEINITSTREAM pfnbeDeinitStream = NULL; - static HINSTANCE hInstEncode = NULL; - - if (((m_hBladeEnc) && (has == (HACMSTREAM)&m_hBladeEnc)) - || ((m_hLameEnc) && (has == (HACMSTREAM)&m_hLameEnc))) - { - PBLADEENCSTREAMINFO pbeCfg = (has == (HACMSTREAM)&m_hBladeEnc) ? gpbeBladeCfg : gpbeLameCfg; - HINSTANCE hLib = *(HINSTANCE *)has; - - if (hInstEncode != hLib) - { - pfnbeEncodeChunk = (BEENCODECHUNK)GetProcAddress(hLib, TEXT_BEENCODECHUNK); - pfnbeDeinitStream = (BEDEINITSTREAM)GetProcAddress(hLib, TEXT_BEDEINITSTREAM); - hInstEncode = hLib; - } - pash->fdwStatus |= ACMSTREAMHEADER_STATUSF_DONE; - if (fdwConvert & ACM_STREAMCONVERTF_END) - { - if ((pfnbeDeinitStream) && (pbeCfg)) - { - pfnbeDeinitStream(pbeCfg->hBeStream, pash->pbDst, &pash->cbDstLengthUsed); - return MMSYSERR_NOERROR; - } - } else - { - if ((pfnbeEncodeChunk) && (pbeCfg)) - { - DWORD dwBytesLeft = pbeCfg->dwInputSamples*2 - pbeCfg->dwReadPos; - if (!dwBytesLeft) - { - dwBytesLeft = pbeCfg->dwInputSamples*2; - pbeCfg->dwReadPos = 0; - } - if (dwBytesLeft > pash->cbSrcLength) dwBytesLeft = pash->cbSrcLength; - memcpy(&pbeCfg->pPCMBuffer[pbeCfg->dwReadPos/2], pash->pbSrc, dwBytesLeft); - pbeCfg->dwReadPos += dwBytesLeft; - pash->cbSrcLengthUsed = dwBytesLeft; - pash->cbDstLengthUsed = 0; - if (pbeCfg->dwReadPos == pbeCfg->dwInputSamples*2) - { - if (pfnbeEncodeChunk(pbeCfg->hBeStream, pbeCfg->dwInputSamples, pbeCfg->pPCMBuffer, pash->pbDst, &pash->cbDstLengthUsed) != 0) return MMSYSERR_INVALPARAM; - pbeCfg->dwReadPos = 0; - } - return MMSYSERR_NOERROR; - } - } - return MMSYSERR_INVALPARAM; - } - if (m_hACMInst) - { - PFNACMSTREAMCONVERT pfnAcmStreamConvert = (PFNACMSTREAMCONVERT)GetProcAddress(m_hACMInst, "acmStreamConvert"); - if (pfnAcmStreamConvert) return pfnAcmStreamConvert(has, pash, fdwConvert); - } - return MMSYSERR_INVALPARAM; -} - - /////////////////////////////////////////////////////////////////////////////////// // // DirectX Plugins @@ -2974,11 +2427,20 @@ #ifdef WIN32 + +typedef BOOL (WINAPI *MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType, + CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, + CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, + CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam + ); + // Try to close the audio device and rescue unsaved work if an unhandled exception occours... -LONG CTrackApp::UnhandledExceptionFilter(_EXCEPTION_POINTERS *) -//------------------------------------------------------------- +LONG CTrackApp::UnhandledExceptionFilter(_EXCEPTION_POINTERS *pExceptionInfo) +//--------------------------------------------------------------------------- { CMainFrame* pMainFrame = CMainFrame::GetMainFrame(); + const HWND window = (pMainFrame ? pMainFrame->m_hWnd : NULL); + // Shut down audio device... if(pMainFrame) { @@ -2986,6 +2448,46 @@ pMainFrame->audioCloseDevice(); } + const CString timestampDir = (CTime::GetCurrentTime()).Format("%Y-%m-%d %H.%M.%S\\"); + CString baseRescuePath; + { + // Create a crash directory + TCHAR tempPath[_MAX_PATH]; + GetTempPath(CountOf(tempPath), tempPath); + baseRescuePath.Format("%sOpenMPT Crash Files\\", tempPath); + CreateDirectory(baseRescuePath, nullptr); + baseRescuePath.Append(timestampDir); + if(!CreateDirectory(baseRescuePath, nullptr)) + { + ::MessageBox(window, "A crash has been detected and OpenMPT will be closed.\nOpenMPT was unable to create a directory for saving debug information and modified files to.", "OpenMPT Crash", MB_ICONERROR); + } + } + + // Create minidump... + HMODULE hDll = ::LoadLibrary("DBGHELP.DLL"); + if (hDll) + { + MINIDUMPWRITEDUMP pDump = (MINIDUMPWRITEDUMP)::GetProcAddress(hDll, "MiniDumpWriteDump"); + if (pDump) + { + const CString filename = baseRescuePath + "crash.dmp"; + + HANDLE hFile = ::CreateFile(filename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile != INVALID_HANDLE_VALUE) + { + _MINIDUMP_EXCEPTION_INFORMATION ExInfo; + + ExInfo.ThreadId = ::GetCurrentThreadId(); + ExInfo.ExceptionPointers = pExceptionInfo; + ExInfo.ClientPointers = NULL; + + pDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL); + ::CloseHandle(hFile); + } + } + ::FreeLibrary(hDll); + } + // Rescue modified files... CDocTemplate *pDocTmpl = theApp.GetModDocTemplate(); if(pDocTmpl) @@ -2993,9 +2495,6 @@ POSITION pos = pDocTmpl->GetFirstDocPosition(); CDocument *pDoc; - const HWND window = (pMainFrame ? pMainFrame->m_hWnd : NULL); - const CString timestampDir = (CTime::GetCurrentTime()).Format("%Y-%m-%d %H.%M.%S\\"); - CString baseRescuePath; int numFiles = 0; while((pos != NULL) && ((pDoc = pDocTmpl->GetNextDoc(pos)) != NULL)) @@ -3005,17 +2504,8 @@ { if(numFiles == 0) { - // Need to create a rescue directory first - TCHAR tempPath[_MAX_PATH]; - GetTempPath(CountOf(tempPath), tempPath); - baseRescuePath.Format("%sOpenMPT Crash Files\\", tempPath); - CreateDirectory(baseRescuePath, nullptr); - baseRescuePath.Append(timestampDir); - if(!CreateDirectory(baseRescuePath, nullptr)) - { - ::MessageBox(window, "A crash has been detected and OpenMPT will be closed.\nThere are still some modified files open, but OpenMPT could not create a directory for rescueing them.", "OpenMPT Crash", MB_ICONERROR); - break; - } + // Show the rescue directory in Explorer... + OpenDirectory(baseRescuePath); } CString filename; filename.Format("%s%d_%s.%s", baseRescuePath, ++numFiles, pModDoc->GetTitle(), pModDoc->GetSoundFile()->GetModSpecifications().fileExtension); @@ -3028,7 +2518,6 @@ CString message; message.Format("A crash has been detected and OpenMPT will be closed.\n%d modified file%s been rescued to\n\n%s\n\nNote: It cannot be guaranteed that rescued files are still intact.", numFiles, (numFiles == 1 ? " has" : "s have"), baseRescuePath); ::MessageBox(window, message, "OpenMPT Crash", MB_ICONERROR); - OpenDirectory(baseRescuePath); } } Modified: trunk/OpenMPT/mptrack/Mptrack.h =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.h 2011-08-22 14:14:03 UTC (rev 992) +++ trunk/OpenMPT/mptrack/Mptrack.h 2011-08-22 18:21:40 UTC (rev 993) @@ -14,26 +14,13 @@ #include "resource.h" // main symbols #include "../soundlib/Sndfile.h" +#include "ACMConvert.h" #include <windows.h> class CModDoc; class CVstPluginManager; ///////////////////////////////////////////////////////////////////////////// -// ACM Functions (for dynamic linking) - -typedef VOID (ACMAPI *PFNACMMETRICS)(HACMOBJ, UINT, LPVOID); -typedef MMRESULT (ACMAPI *PFNACMFORMATENUM)(HACMDRIVER, LPACMFORMATDETAILSA, ACMFORMATENUMCBA, DWORD dwInstance, DWORD fdwEnum); -typedef MMRESULT (ACMAPI *PFNACMDRIVEROPEN)(LPHACMDRIVER, HACMDRIVERID, DWORD); -typedef MMRESULT (ACMAPI *PFNACMDRIVERCLOSE)(HACMDRIVER, DWORD); -typedef MMRESULT (ACMAPI *PFNACMSTREAMOPEN)(LPHACMSTREAM, HACMDRIVER, LPWAVEFORMATEX, LPWAVEFORMATEX, LPWAVEFILTER, DWORD, DWORD, DWORD); -typedef MMRESULT (ACMAPI *PFNACMSTREAMCLOSE)(HACMSTREAM, DWORD); -typedef MMRESULT (ACMAPI *PFNACMSTREAMSIZE)(HACMSTREAM, DWORD, LPDWORD, DWORD); -typedef MMRESULT (ACMAPI *PFNACMSTREAMCONVERT)(HACMSTREAM, LPACMSTREAMHEADER, DWORD); -typedef MMRESULT (ACMAPI *PFNACMDRIVERDETAILS)(HACMDRIVERID, LPACMDRIVERDETAILS, DWORD); - - -///////////////////////////////////////////////////////////////////////////// // 16-colors DIB typedef struct MODPLUGDIB { @@ -141,7 +128,7 @@ protected: CMultiDocTemplate *m_pModTemplate; CVstPluginManager *m_pPluginManager; - BOOL m_bInitialized, m_bLayer3Present, m_bExWaveSupport, m_bDebugMode; + BOOL m_bInitialized, m_bExWaveSupport, m_bDebugMode; DWORD m_dwTimeStarted, m_dwLastPluginIdleCall; HANDLE m_hAlternateResourceHandle; // Default macro configuration @@ -152,6 +139,7 @@ TCHAR m_szPluginCacheFileName[_MAX_PATH]; TCHAR m_szStringsFileName[_MAX_PATH]; static bool m_bPortableMode; + ACMConvert acmConvert; public: CTrackApp(); @@ -188,7 +176,7 @@ void SetDefaultMidiMacro(const MODMIDICFG *pcfg) { m_MidiCfg = *pcfg; } void LoadChords(PMPTCHORD pChords); void SaveChords(PMPTCHORD pChords); - BOOL CanEncodeLayer3() const { return m_bLayer3Present; } + BOOL CanEncodeLayer3() const { return acmConvert.IsLayer3Present(); } BOOL IsWaveExEnabled() const { return m_bExWaveSupport; } BOOL IsDebug() const { return m_bDebugMode; } LPCTSTR GetConfigFileName() const { return m_szConfigFileName; } @@ -207,6 +195,8 @@ /// Removes item from MRU-list; most recent item has index zero. void RemoveMruItem(const int nItem); + ACMConvert &GetACMConvert() { return acmConvert; }; + // Splash Screen protected: VOID StartSplashScreen(); @@ -217,32 +207,6 @@ VOID ImportLocalizedStrings(); BOOL GetLocalizedString(LPCSTR pszName, LPSTR pszStr, UINT cbSize); -// ACM and MPEG Layer3 support -protected: - HINSTANCE m_hACMInst; - HINSTANCE m_hBladeEnc, m_hLameEnc; - PFNACMFORMATENUM m_pfnAcmFormatEnum; - -public: - BOOL InitializeACM(BOOL bNoAcm=FALSE); - BOOL UninitializeACM(); - BOOL InitializeDXPlugins(); - BOOL UninitializeDXPlugins(); - static void AcmExceptionHandler(); - MMRESULT AcmFormatEnum(HACMDRIVER had, LPACMFORMATDETAILSA pafd, ACMFORMATENUMCBA fnCallback, DWORD dwInstance, DWORD fdwEnum); - MMRESULT AcmDriverOpen(LPHACMDRIVER, HACMDRIVERID, DWORD); - MMRESULT AcmDriverDetails(HACMDRIVERID hadid, LPACMDRIVERDETAILS padd, DWORD fdwDetails); - MMRESULT AcmDriverClose(HACMDRIVER, DWORD); - MMRESULT AcmStreamOpen(LPHACMSTREAM, HACMDRIVER, LPWAVEFORMATEX, LPWAVEFORMATEX, LPWAVEFILTER pwfltr, DWORD dwCallback, DWORD dwInstance, DWORD fdwOpen); - MMRESULT AcmStreamClose(HACMSTREAM, DWORD); - MMRESULT AcmStreamSize(HACMSTREAM has, DWORD cbInput, LPDWORD pdwOutputBytes, DWORD fdwSize); - MMRESULT AcmStreamPrepareHeader(HACMSTREAM has, LPACMSTREAMHEADER pash, DWORD fdwPrepare); - MMRESULT AcmStreamUnprepareHeader(HACMSTREAM has, LPACMSTREAMHEADER pash, DWORD fdwUnprepare); - MMRESULT AcmStreamConvert(HACMSTREAM has, LPACMSTREAMHEADER pash, DWORD fdwConvert); - -protected: - static BOOL CALLBACK AcmFormatEnumCB(HACMDRIVERID, LPACMFORMATDETAILS, DWORD, DWORD); - // Overrides public: // ClassWizard generated virtual function overrides @@ -274,9 +238,14 @@ DECLARE_MESSAGE_MAP() virtual LRESULT ProcessWndProcException(CException* e, const MSG* pMsg); -private: +protected: static void LoadRegistryDLS(); +protected: + BOOL InitializeDXPlugins(); + BOOL UninitializeDXPlugins(); + + #ifdef WIN32 // Legacy stuff bool MoveConfigFile(TCHAR sFileName[_MAX_PATH], TCHAR sSubDir[_MAX_PATH] = "", TCHAR sNewFileName[_MAX_PATH] = ""); #endif // WIN32 @@ -284,7 +253,7 @@ // Exception handling #ifdef WIN32 public: - static LONG WINAPI UnhandledExceptionFilter(_EXCEPTION_POINTERS *); + static LONG WINAPI UnhandledExceptionFilter(_EXCEPTION_POINTERS *pExceptionInfo); #endif // WIN32 }; Modified: trunk/OpenMPT/mptrack/mptrack.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack.vcproj 2011-08-22 14:14:03 UTC (rev 992) +++ trunk/OpenMPT/mptrack/mptrack.vcproj 2011-08-22 18:21:40 UTC (rev 993) @@ -178,6 +178,9 @@ RelativePath=".\AbstractVstEditor.cpp"> </File> <File + RelativePath=".\ACMConvert.cpp"> + </File> + <File RelativePath=".\ArrayUtils.cpp"> </File> <File @@ -660,6 +663,9 @@ RelativePath=".\AbstractVstEditor.h"> </File> <File + RelativePath=".\ACMConvert.h"> + </File> + <File RelativePath=".\ArrayUtils.h"> </File> <File Modified: trunk/OpenMPT/mptrack/mptrack_08.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_08.vcproj 2011-08-22 14:14:03 UTC (rev 992) +++ trunk/OpenMPT/mptrack/mptrack_08.vcproj 2011-08-22 18:21:40 UTC (rev 993) @@ -241,6 +241,10 @@ > </File> <File + RelativePath=".\ACMConvert.cpp" + > + </File> + <File RelativePath=".\ArrayUtils.cpp" > </File> @@ -875,6 +879,10 @@ > </File> <File + RelativePath=".\ACMConvert.h" + > + </File> + <File RelativePath=".\ArrayUtils.h" > </File> Modified: trunk/OpenMPT/mptrack/mptrack_10.vcxproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_10.vcxproj 2011-08-22 14:14:03 UTC (rev 992) +++ trunk/OpenMPT/mptrack/mptrack_10.vcxproj 2011-08-22 18:21:40 UTC (rev 993) @@ -117,7 +117,6 @@ <TypeLibraryName>.\Bin/mptrack.tlb</TypeLibraryName> </Midl> <ClCompile> - <AdditionalOptions>/EHsc /O2 %(AdditionalOptions)</AdditionalOptions> <Optimization>MaxSpeed</Optimization> <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion> <AdditionalIncludeDirectories>..\unlha;..\unzip;..\unrar;..\soundlib;..\include;..\xsoundlib;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> @@ -137,6 +136,8 @@ <SuppressStartupBanner>false</SuppressStartupBanner> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <CompileAs>Default</CompileAs> + <ExceptionHandling>Async</ExceptionHandling> + <AdditionalOptions>/O2 %(AdditionalOptions)</AdditionalOptions> </ClCompile> <ResourceCompile> <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> @@ -165,6 +166,7 @@ </ItemDefinitionGroup> <ItemGroup> <ClCompile Include="AbstractVstEditor.cpp" /> + <ClCompile Include="ACMConvert.cpp" /> <ClCompile Include="ArrayUtils.cpp" /> <ClCompile Include="AutoSaver.cpp" /> <ClCompile Include="ChannelManagerDlg.cpp" /> @@ -314,6 +316,7 @@ <ResourceCompile Include="mptrack.rc" /> </ItemGroup> <ItemGroup> + <ClInclude Include="ACMConvert.h" /> <ClInclude Include="PatternRandomizer.h" /> <ClInclude Include="PatternRandomizerGUI.h" /> <ClInclude Include="PatternRandomizerGUIEffect.h" /> Modified: trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters =================================================================== --- trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters 2011-08-22 14:14:03 UTC (rev 992) +++ trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters 2011-08-22 18:21:40 UTC (rev 993) @@ -421,6 +421,9 @@ <ClCompile Include="SelectPluginDialog.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="ACMConvert.cpp"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="AbstractVstEditor.h"> @@ -735,6 +738,9 @@ <ClInclude Include="SelectPluginDialog.h"> <Filter>Header Files\Dialogs</Filter> </ClInclude> + <ClInclude Include="ACMConvert.h"> + <Filter>Header Files</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <None Include="res\bitmap1.bmp"> Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2011-08-22 14:14:03 UTC (rev 992) +++ trunk/OpenMPT/mptrack/version.h 2011-08-22 18:21:40 UTC (rev 993) @@ -15,7 +15,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 20 #define VER_MINOR 00 -#define VER_MINORMINOR 10 +#define VER_MINORMINOR 11 //Creates version number from version parts that appears in version string. //For example MAKE_VERSION_NUMERIC(1,17,02,28) gives version number of Th... [truncated message content] |