From: <man...@us...> - 2013-09-09 16:45:01
|
Revision: 2682 http://sourceforge.net/p/modplug/code/2682 Author: manxorist Date: 2013-09-09 16:44:47 +0000 (Mon, 09 Sep 2013) Log Message: ----------- Merged revision(s) 2653-2654, 2660, 2664, 2678, 2681 from branches/manx/lossy-export: [Imp] mod2wav: Use a common dialog for wav and compressed exporting. [New] mod2wav: Allow all the filtering options available for wav export also for lossy export. [New] mod2wav: Support normalizing compressed outputs. [New] mod2wav: Support tagging wav files. [Ref] mod2wav: Rewrite MP3 export code via BladeEnc and Windows ACM APIs, implementing a clean codec interface. [New] mod2wav: Add MP3 export using native libmp3lame interface. [Imp] mod2wav: Be explicit to the user about which MP3 codec is used when exporting. [New] mod2wav: Add FLAC export. [Mod] mod2wav: Avoid fiddling with sample preamp when exporting. [Mod] Remove /noacm command line option. All supported windows versions have the required ACM version available. [Ref] Support writing to std::ostream in WavWriter. [Ref] Cleanup .wav and .mp3 tagging code. [Mod] Rename file export menu entries. ........ [New] mod2wav: Support exporting to Ogg Vorbis encoded files using externally-supplied vorbis and ogg DLLs. [New] mod2wav: Support exporting to IETF Opus encoded files using externally-supplied opus and ogg DLLs. [Var] Add headers from libogg v1.3.1 [Var] Add headers from libvorbis v1.3.3 [Var] Add headers from libopus v1.1-beta [Var] Add opus_header.[ch] from opus-tools v0.1.6 ........ [Ref] When rendering a song, always set mixer setting MaxMixChannels to MAX_CHANNELS instead of checking at every occasion if we are actually rendering. ........ [Fix] mod2wav: Write file tags in proper character encoding. ........ [Fix] mod2wav: Re-add genre list from lame mp3 codec. ........ [Ref] mod2wav: Cleanup codec naming. ........ Modified Paths: -------------- trunk/OpenMPT/libopenmpt/libopenmpt.vcxproj trunk/OpenMPT/libopenmpt/libopenmpt.vcxproj.filters trunk/OpenMPT/mptrack/CommandSet.cpp trunk/OpenMPT/mptrack/InputHandler.cpp trunk/OpenMPT/mptrack/Mod2wave.cpp trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/mptrack/TrackerSettings.cpp trunk/OpenMPT/mptrack/TrackerSettings.h trunk/OpenMPT/mptrack/mod2wave.h trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/mptrack/mptrack_08.vcproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj trunk/OpenMPT/mptrack/mptrack_10.vcxproj.filters trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/soundlib/Fastmix.cpp trunk/OpenMPT/soundlib/SampleFormat.h trunk/OpenMPT/soundlib/SampleFormats.cpp trunk/OpenMPT/soundlib/Sndmix.cpp trunk/OpenMPT/soundlib/WAVTools.cpp trunk/OpenMPT/soundlib/WAVTools.h Added Paths: ----------- trunk/OpenMPT/include/ogg/ trunk/OpenMPT/include/opus/ trunk/OpenMPT/include/vorbis/ trunk/OpenMPT/mptrack/StreamEncoder.cpp trunk/OpenMPT/mptrack/StreamEncoder.h trunk/OpenMPT/mptrack/StreamEncoderFLAC.cpp trunk/OpenMPT/mptrack/StreamEncoderFLAC.h trunk/OpenMPT/mptrack/StreamEncoderMP3.cpp trunk/OpenMPT/mptrack/StreamEncoderMP3.h trunk/OpenMPT/mptrack/StreamEncoderOpus.cpp trunk/OpenMPT/mptrack/StreamEncoderOpus.h trunk/OpenMPT/mptrack/StreamEncoderVorbis.cpp trunk/OpenMPT/mptrack/StreamEncoderVorbis.h trunk/OpenMPT/mptrack/StreamEncoderWAV.cpp trunk/OpenMPT/mptrack/StreamEncoderWAV.h trunk/OpenMPT/soundlib/Tagging.cpp trunk/OpenMPT/soundlib/Tagging.h Removed Paths: ------------- trunk/OpenMPT/mptrack/ACMConvert.cpp trunk/OpenMPT/mptrack/ACMConvert.h trunk/OpenMPT/mptrack/tagging.cpp trunk/OpenMPT/mptrack/tagging.h Property Changed: ---------------- trunk/OpenMPT/ Index: trunk/OpenMPT =================================================================== --- trunk/OpenMPT 2013-09-09 15:37:16 UTC (rev 2681) +++ trunk/OpenMPT 2013-09-09 16:44:47 UTC (rev 2682) Property changes on: trunk/OpenMPT ___________________________________________________________________ Modified: svn:mergeinfo ## -2,6 +2,8 ## /branches/manx/gcc-fixes:2018-2022,2024-2048,2052-2071,2075-2077,2080,2087-2089 /branches/manx/header-dependencies-cleanups:1394-1397,1401-1402,1405-1406 /branches/manx/instrument-fields-fixes:2203-2238 +/branches/manx/lossy-export:2653-2654,2660,2664,2678,2681 +/branches/manx/lossy-export-xiph:2663,2677,2680 /branches/manx/mptstring-stdstring-support:2204,2208,2212,2214,2217,2220,2224,2259,2261-2262,2264,2267 /branches/manx/nonglobal-mixer:1715-1841 /branches/manx/premake:2606,2609-2610,2614,2616,2621,2624,2641 \ No newline at end of property Modified: trunk/OpenMPT/libopenmpt/libopenmpt.vcxproj =================================================================== --- trunk/OpenMPT/libopenmpt/libopenmpt.vcxproj 2013-09-09 15:37:16 UTC (rev 2681) +++ trunk/OpenMPT/libopenmpt/libopenmpt.vcxproj 2013-09-09 16:44:47 UTC (rev 2682) @@ -464,6 +464,7 @@ <ClInclude Include="..\soundlib\Snd_defs.h" /> <ClInclude Include="..\soundlib\SoundFilePlayConfig.h" /> <ClInclude Include="..\soundlib\Tables.h" /> + <ClInclude Include="..\soundlib\Tagging.h" /> <ClInclude Include="..\soundlib\tuning.h" /> <ClInclude Include="..\soundlib\tuningbase.h" /> <ClInclude Include="..\soundlib\tuningcollection.h" /> @@ -551,6 +552,7 @@ <ClCompile Include="..\soundlib\Snd_fx.cpp" /> <ClCompile Include="..\soundlib\SoundFilePlayConfig.cpp" /> <ClCompile Include="..\soundlib\Tables.cpp" /> + <ClCompile Include="..\soundlib\Tagging.cpp" /> <ClCompile Include="..\soundlib\tuning.cpp" /> <ClCompile Include="..\soundlib\tuningbase.cpp" /> <ClCompile Include="..\soundlib\tuningCollection.cpp" /> Modified: trunk/OpenMPT/libopenmpt/libopenmpt.vcxproj.filters =================================================================== --- trunk/OpenMPT/libopenmpt/libopenmpt.vcxproj.filters 2013-09-09 15:37:16 UTC (rev 2681) +++ trunk/OpenMPT/libopenmpt/libopenmpt.vcxproj.filters 2013-09-09 16:44:47 UTC (rev 2682) @@ -245,6 +245,9 @@ <ClInclude Include="..\soundlib\SampleFormat.h"> <Filter>Header Files\soundlib</Filter> </ClInclude> + <ClInclude Include="..\soundlib\Tagging.h"> + <Filter>Header Files\soundlib</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <ClCompile Include="..\common\AudioCriticalSection.cpp"> @@ -502,5 +505,8 @@ <ClCompile Include="..\soundlib\MixerLoops.cpp"> <Filter>Source Files\soundlib</Filter> </ClCompile> + <ClCompile Include="..\soundlib\Tagging.cpp"> + <Filter>Source Files\soundlib</Filter> + </ClCompile> </ItemGroup> </Project> \ No newline at end of file Deleted: trunk/OpenMPT/mptrack/ACMConvert.cpp =================================================================== --- trunk/OpenMPT/mptrack/ACMConvert.cpp 2013-09-09 15:37:16 UTC (rev 2681) +++ trunk/OpenMPT/mptrack/ACMConvert.cpp 2013-09-09 16:44:47 UTC (rev 2682) @@ -1,532 +0,0 @@ -/* - * ACMConvert.cpp - * -------------- - * Purpose: MPEG Layer-3 Functions through ACM. - * Notes : Access to LAMEenc and BLADEenc is emulated through the ACM interface. - * Authors: Olivier Lapicque - * OpenMPT Devs - * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. - */ - - -#include "stdafx.h" -#include <bladeenc/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; - - -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) - { - try { - m_hACMInst = LoadLibrary(TEXT("MSACM32.DLL")); - } catch(...) - { - m_hACMInst = NULL; - } - } - 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; - } - try { - *(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); - bOk = TRUE; - } - } catch(...) - { - // nothing - } - return bOk; -} - - -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; - } - layer3Present = FALSE; - return TRUE; -} - - -MMRESULT ACMConvert::AcmFormatEnum(HACMDRIVER had, LPACMFORMATDETAILSA pafd, ACMFORMATENUMCBA fnCallback, DWORD_PTR 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_PTR, 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_PTR dwCallback, // callback - DWORD_PTR 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; -} Deleted: trunk/OpenMPT/mptrack/ACMConvert.h =================================================================== --- trunk/OpenMPT/mptrack/ACMConvert.h 2013-09-09 15:37:16 UTC (rev 2681) +++ trunk/OpenMPT/mptrack/ACMConvert.h 2013-09-09 16:44:47 UTC (rev 2682) @@ -1,71 +0,0 @@ -/* - * ACMConvert.h - * ------------ - * Purpose: MPEG Layer-3 Functions through ACM. - * Notes : Access to LAMEenc and BLADEenc is emulated through the ACM interface. - * Authors: Olivier Lapicque - * OpenMPT Devs - * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. - */ - - -#pragma once - -///////////////////////////////////////////////////////////////////////////// -// ACM Functions (for dynamic linking) - -typedef VOID (ACMAPI *PFNACMMETRICS)(HACMOBJ, UINT, LPVOID); -typedef MMRESULT (ACMAPI *PFNACMFORMATENUM)(HACMDRIVER, LPACMFORMATDETAILSA, ACMFORMATENUMCBA, DWORD_PTR 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_PTR, DWORD_PTR, 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; - -private: - BOOL InitializeACM(BOOL bNoAcm = FALSE); - BOOL UninitializeACM(); -public: - MMRESULT AcmFormatEnum(HACMDRIVER had, LPACMFORMATDETAILSA pafd, ACMFORMATENUMCBA fnCallback, DWORD_PTR 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_PTR dwCallback, DWORD_PTR 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(bool noACM) - { - layer3Present = FALSE; - m_hBladeEnc = NULL; - m_hLameEnc = NULL; - m_hACMInst = NULL; - m_pfnAcmFormatEnum = NULL; - InitializeACM(noACM); - } - ~ACMConvert() - { - UninitializeACM(); - } - -protected: - static BOOL CALLBACK AcmFormatEnumCB(HACMDRIVERID, LPACMFORMATDETAILS, DWORD_PTR, DWORD); - -}; Modified: trunk/OpenMPT/mptrack/CommandSet.cpp =================================================================== --- trunk/OpenMPT/mptrack/CommandSet.cpp 2013-09-09 15:37:16 UTC (rev 2681) +++ trunk/OpenMPT/mptrack/CommandSet.cpp 2013-09-09 16:44:47 UTC (rev 2682) @@ -433,8 +433,8 @@ DefineKeyCommand(kcFileClose, 1348, _T("File/Close")); DefineKeyCommand(kcFileSave, 1349, _T("File/Save")); DefineKeyCommand(kcFileSaveAs, 1350, _T("File/Save As")); - DefineKeyCommand(kcFileSaveAsWave, 1351, _T("File/Export as Wave")); - DefineKeyCommand(kcFileSaveAsMP3, 1352, _T("File/Export as MP3")); + DefineKeyCommand(kcFileSaveAsWave, 1351, _T("File/Export as lossless (Wave, FLAC)")); + DefineKeyCommand(kcFileSaveAsMP3, 1352, _T("File/Export as lossy (Opus, Vorbis, MP3")); DefineKeyCommand(kcFileSaveMidi, 1353, _T("File/Export as MIDI")); DefineKeyCommand(kcFileImportMidiLib, 1354, _T("File/Import MIDI Library")); DefineKeyCommand(kcFileAddSoundBank, 1355, _T("File/Add Sound Bank")); Modified: trunk/OpenMPT/mptrack/InputHandler.cpp =================================================================== --- trunk/OpenMPT/mptrack/InputHandler.cpp 2013-09-09 15:37:16 UTC (rev 2681) +++ trunk/OpenMPT/mptrack/InputHandler.cpp 2013-09-09 16:44:47 UTC (rev 2682) @@ -502,8 +502,8 @@ case ID_FILE_SAVE: s="&Save\t"; c = kcFileSave; break; case ID_FILE_SAVE_AS: s="Save &As...\t"; c = kcFileSaveAs; break; case ID_FILE_SAVEASTEMPLATE:s="Sa&ve as Template\t"; c = kcFileSaveTemplate; break; - case ID_FILE_SAVEASWAVE: s="Export as &Wave...\t"; c = kcFileSaveAsWave; break; - case ID_FILE_SAVEASMP3: s="Export as M&P3...\t"; c = kcFileSaveAsMP3; break; + case ID_FILE_SAVEASWAVE: s="Export as lossless (&Wave, FLAC)...\t"; c = kcFileSaveAsWave; break; + case ID_FILE_SAVEASMP3: s="Export as lossy (Opus, Vorbis, M&P3)...\t"; c = kcFileSaveAsMP3; break; case ID_FILE_SAVEMIDI: s="Export as M&IDI...\t"; c = kcFileSaveMidi; break; case ID_FILE_SAVECOMPAT: s="Compatibility &Export...\t"; c = kcFileExportCompat; break; case ID_IMPORT_MIDILIB: s="Import &MIDI Library...\t"; c = kcFileImportMidiLib; break; Modified: trunk/OpenMPT/mptrack/Mod2wave.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mod2wave.cpp 2013-09-09 15:37:16 UTC (rev 2681) +++ trunk/OpenMPT/mptrack/Mod2wave.cpp 2013-09-09 16:44:47 UTC (rev 2682) @@ -18,8 +18,8 @@ #include "mod2wave.h" #include "Wav.h" #include "WAVTools.h" +#include "../common/mptString.h" #include "../common/version.h" -#include "ACMConvert.h" #include "../soundlib/MixerLoops.h" #include "../soundlib/Dither.h" #include "../soundlib/AudioReadTarget.h" @@ -28,7 +28,6 @@ extern LPCSTR gszChnCfgNames[3]; - static CSoundFile::samplecount_t ReadInterleaved(CSoundFile &sndFile, void *outputBuffer, CSoundFile::samplecount_t count, SampleFormat sampleFormat, Dither &dither) //------------------------------------------------------------------------------------------------------------------------------------------------------------------- { @@ -80,54 +79,6 @@ return 0; } - -static const GUID guid_MEDIASUBTYPE_PCM = {0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71}; -static const GUID guid_MEDIASUBTYPE_IEEE_FLOAT = {0x00000003, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B, 0x71}; - -/////////////////////////////////////////////////////////////////////////////////////////////////// -// ID3v1 Genres - -static const char *id3v1GenreNames[] = -{ - "Blues", "Classic Rock", "Country", "Dance", - "Disco", "Funk", "Grunge", "Hip-Hop", - "Jazz", "Metal", "New Age", "Oldies", - "Other", "Pop", "R&B", "Rap", - "Reggae", "Rock", "Techno", "Industrial", - "Alternative", "Ska", "Death Metal", "Pranks", - "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop", - "Vocal", "Jazz+Funk", "Fusion", "Trance", - "Classical", "Instrumental", "Acid", "House", - "Game", "Sound Clip", "Gospel", "Noise", - "Alt. Rock", "Bass", "Soul", "Punk", - "Space", "Meditative", "Instrumental Pop", "Instrumental Rock", - "Ethnic", "Gothic", "Darkwave", "Techno-Industrial", - "Electronic", "Pop-Folk", "Eurodance", "Dream", - "Southern Rock", "Comedy", "Cult", "Gangsta", - "Top 40", "Christian Rap", "Pop/Funk", "Jungle", - "Native American", "Cabaret", "New Wave", "Psychadelic", - "Rave", "Showtunes", "Trailer", "Lo-Fi", - "Tribal", "Acid Punk", "Acid Jazz", "Polka", - "Retro", "Musical", "Rock & Roll", "Hard Rock", - "Folk", "Folk-Rock", "National Folk", "Swing", - "Fast Fusion", "Bebob", "Latin", "Revival", - "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock", - "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock", - "Big Band", "Chorus", "Easy Listening", "Acoustic", - "Humour", "Speech", "Chanson", "Opera", - "Chamber Music", "Sonata", "Symphony", "Booty Bass", - "Primus", "Porn Groove", "Satire", "Slow Jam", - "Club", "Tango", "Samba", "Folklore", - "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", - "Duet", "Punk Rock", "Drum Solo", "A Capella", - "Euro-House", "Dance Hall", "Goa", "Drum & Bass", - "Club House", "Hardcore", "Terror", "Indie", - "BritPop", "Negerpunk", "Polsk Punk", "Beat", - "Christian Gangsta Rap","Heavy Metal", "Black Metal", "Crossover", - "Contemporary Christian", "Christian Rock", "Merengue", "Salsa", - "Thrash Metal", "Anime", "JPop", "Synthpop" -}; - /////////////////////////////////////////////////// // CWaveConvert - setup for converting a wave file @@ -139,15 +90,22 @@ ON_COMMAND(IDC_RADIO1, UpdateDialog) ON_COMMAND(IDC_RADIO2, UpdateDialog) ON_COMMAND(IDC_PLAYEROPTIONS, OnPlayerOptions) //rewbs.resamplerConf + ON_CBN_SELCHANGE(IDC_COMBO5, OnFileTypeChanged) + ON_CBN_SELCHANGE(IDC_COMBO1, OnSamplerateChanged) + ON_CBN_SELCHANGE(IDC_COMBO4, OnChannelsChanged) ON_CBN_SELCHANGE(IDC_COMBO2, OnFormatChanged) END_MESSAGE_MAP() -CWaveConvert::CWaveConvert(CWnd *parent, ORDERINDEX minOrder, ORDERINDEX maxOrder, ORDERINDEX numOrders) : CDialog(IDD_WAVECONVERT, parent) -//----------------------------------------------------------------------------------------------------------------------------------------- +CWaveConvert::CWaveConvert(CWnd *parent, ORDERINDEX minOrder, ORDERINDEX maxOrder, ORDERINDEX numOrders, CSoundFile *sndfile, std::size_t defaultEncoder, const std::vector<EncoderFactoryBase*> &encFactories) +//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + : CDialog(IDD_WAVECONVERT, parent) + , m_Settings(defaultEncoder, encFactories) { + ASSERT(!encFactories.empty()); + encTraits = m_Settings.GetTraits(); + m_pSndFile = sndfile; m_bGivePlugsIdleTime = false; - m_bNormalize = false; m_bHighQuality = false; m_bSelectPlay = false; if(minOrder != ORDERINDEX_INVALID && maxOrder != ORDERINDEX_INVALID) @@ -165,13 +123,6 @@ m_dwFileLimit = 0; m_dwSongLimit = 0; - MemsetZero(WaveFormat); - WaveFormat.Format.wFormatTag = WAVE_FORMAT_PCM; - WaveFormat.Format.nChannels = 2; - WaveFormat.Format.nSamplesPerSec = 44100; - WaveFormat.Format.wBitsPerSample = 16; - WaveFormat.Format.nBlockAlign = (WaveFormat.Format.wBitsPerSample * WaveFormat.Format.nChannels) / 8; - WaveFormat.Format.nAvgBytesPerSec = WaveFormat.Format.nSamplesPerSec * WaveFormat.Format.nBlockAlign; } @@ -179,23 +130,31 @@ //--------------------------------------------------- { CDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_COMBO5, m_CbnFileType); DDX_Control(pDX, IDC_COMBO1, m_CbnSampleRate); + DDX_Control(pDX, IDC_COMBO4, m_CbnChannels); DDX_Control(pDX, IDC_COMBO2, m_CbnSampleFormat); DDX_Control(pDX, IDC_SPIN3, m_SpinMinOrder); DDX_Control(pDX, IDC_SPIN4, m_SpinMaxOrder); DDX_Control(pDX, IDC_SPIN5, m_SpinLoopCount); + + DDX_Control(pDX, IDC_COMBO3, m_CbnGenre); + DDX_Control(pDX, IDC_EDIT11, m_EditTitle); + DDX_Control(pDX, IDC_EDIT6, m_EditAuthor); + DDX_Control(pDX, IDC_EDIT7, m_EditAlbum); + DDX_Control(pDX, IDC_EDIT8, m_EditURL); + DDX_Control(pDX, IDC_EDIT9, m_EditYear); + + DDX_Control(pDX, IDC_EDIT10, m_EditInfo); } BOOL CWaveConvert::OnInitDialog() //------------------------------- { - CHAR s[128]; - CDialog::OnInitDialog(); CheckRadioButton(IDC_RADIO1, IDC_RADIO2, m_bSelectPlay ? IDC_RADIO2 : IDC_RADIO1); - CheckDlgButton(IDC_CHECK3, MF_CHECKED); // HQ resampling CheckDlgButton(IDC_CHECK5, MF_UNCHECKED); // rewbs.NoNormalize CheckDlgButton(IDC_CHECK4, MF_UNCHECKED); @@ -209,41 +168,240 @@ SetDlgItemInt(IDC_EDIT5, loopCount, FALSE); m_SpinLoopCount.SetRange(1, int16_max); - const std::vector<uint32> samplerates = TrackerSettings::Instance().GetSampleRates(); - for(size_t i = 0; i < samplerates.size(); i++) + FillFileTypes(); + FillSamplerates(); + FillChannels(); + FillFormats(); + + SetDlgItemText(IDC_EDIT11, m_pSndFile->GetTitle().c_str()); + m_EditYear.SetLimitText(4); + CTime tTime = CTime::GetCurrentTime(); + m_EditYear.SetWindowText(tTime.Format("%Y")); + + FillTags(); + + FillInfo(); + + UpdateDialog(); + return TRUE; +} + + +void CWaveConvert::FillTags() +//--------------------------- +{ + const bool canTags = encTraits->canTags; + + CheckDlgButton(IDC_CHECK7, canTags?m_Settings.EncoderSettings.Tags?TRUE:FALSE:FALSE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_CHECK7), canTags?TRUE:FALSE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_COMBO3), canTags?TRUE:FALSE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_EDIT11), canTags?TRUE:FALSE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_EDIT6), canTags?TRUE:FALSE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_EDIT7), canTags?TRUE:FALSE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_EDIT8), canTags?TRUE:FALSE); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_EDIT9), canTags?TRUE:FALSE); + + m_CbnGenre.ResetContent(); + if(!encTraits->genres.empty()) { - UINT n = samplerates[i]; - wsprintf(s, "%d Hz", n); - m_CbnSampleRate.SetItemData(m_CbnSampleRate.AddString(s), n); - if (n == WaveFormat.Format.nSamplesPerSec) m_CbnSampleRate.SetCurSel(i); + for(std::vector<std::string>::const_iterator genre = encTraits->genres.begin(); genre != encTraits->genres.end(); ++genre) + { + m_CbnGenre.AddString((*genre).c_str()); + } } - for (UINT j=0; j<3*4; j++) +} + + +void CWaveConvert::FillInfo() +//--------------------------- +{ + + std::string info; + info += "Format: "; + info += encTraits->fileDescription; + info += "\r\n"; + info += "Encoder: "; + info += encTraits->encoderName; + info += "\r\n"; + info += mpt::String::Replace(encTraits->description, "\n", "\r\n"); + SetDlgItemText(IDC_EDIT10, info.c_str()); +} + + +void CWaveConvert::FillFileTypes() +//-------------------------------- +{ + m_CbnFileType.ResetContent(); + int sel = 0; + for(std::size_t i = 0; i < m_Settings.EncoderFactories.size(); ++i) { - UINT n = 3*4-1-j; - UINT nBits = 8 * (1 + n % 4); - UINT nChannels = 1 << (n/4); - if ((nBits >= 16) || (nChannels <= 2)) + const Encoder::Traits &encTraits = m_Settings.EncoderFactories[i]->GetTraits(); + int ndx = m_CbnFileType.AddString(encTraits.fileShortDescription.c_str()); + m_CbnFileType.SetItemData(ndx, i); + } + m_CbnFileType.SetCurSel(sel); +} + + +void CWaveConvert::FillSamplerates() +//---------------------------------- +{ + m_CbnSampleRate.CComboBox::ResetContent(); + int sel = 0; + for(std::vector<uint32>::const_iterator it = encTraits->samplerates.begin(); it != encTraits->samplerates.end(); ++it) + { + uint32 samplerate = *it; + int ndx = m_CbnSampleRate.AddString(mpt::String::Format("%d Hz", samplerate).c_str()); + m_CbnSampleRate.SetItemData(ndx, samplerate); + if(samplerate == m_Settings.SampleRate) { - wsprintf(s, "%s, %d-Bit", gszChnCfgNames[n/4], nBits); - UINT ndx = m_CbnSampleFormat.AddString(s); - m_CbnSampleFormat.SetItemData(ndx, (nChannels<<8)|nBits); - if ((nBits == WaveFormat.Format.wBitsPerSample) && (nChannels == WaveFormat.Format.nChannels)) + sel = ndx; + } + } + m_CbnSampleRate.SetCurSel(sel); +} + + +void CWaveConvert::FillChannels() +//------------------------------- +{ + m_CbnChannels.CComboBox::ResetContent(); + int sel = 0; + for(int channels = 4; channels >= 1; channels /= 2) + { + if(channels > encTraits->maxChannels) + { + continue; + } + int ndx = m_CbnChannels.AddString(gszChnCfgNames[(channels+2)/2-1]); + m_CbnChannels.SetItemData(ndx, channels); + if(channels == m_Settings.Channels) + { + sel = ndx; + } + } + m_CbnChannels.SetCurSel(sel); +} + + +void CWaveConvert::FillFormats() +//------------------------------ +{ + m_CbnSampleFormat.CComboBox::ResetContent(); + int sel = 0; + DWORD dwSamplerate = m_CbnSampleRate.GetItemData(m_CbnSampleRate.GetCurSel()); + INT nChannels = m_CbnChannels.GetItemData(m_CbnChannels.GetCurSel()); + if(encTraits->modes & Encoder::ModeQuality) + { + for(int quality = 100; quality >= 0; quality -= 10) + { + int ndx = m_CbnSampleFormat.AddString(m_Settings.GetEncoderFactory()->DescribeQuality(quality * 0.01f).c_str()); + m_CbnSampleFormat.SetItemData(ndx, (Encoder::ModeQuality<<24) | (quality<<0)); + if(m_Settings.EncoderSettings.Mode == Encoder::ModeQuality && Util::Round<int>(m_Settings.EncoderSettings.Quality*100.0f) == quality) { - m_CbnSampleFormat.SetCurSel(ndx); + sel = ndx; } } } + if(encTraits->modes & Encoder::ModeVBR) + { + for(int bitrate = encTraits->bitrates.size()-1; bitrate >= 0; --bitrate) + { + int ndx = m_CbnSampleFormat.AddString(mpt::String::Format("VBR %i kbit", encTraits->bitrates[bitrate]).c_str()); + m_CbnSampleFormat.SetItemData(ndx, (Encoder::ModeVBR<<24) | (encTraits->bitrates[bitrate]<<0)); + if(m_Settings.EncoderSettings.Mode == Encoder::ModeVBR && static_cast<int>(m_Settings.EncoderSettings.Bitrate) == encTraits->bitrates[bitrate]) + { + sel = ndx; + } + } + } + if(encTraits->modes & Encoder::ModeABR) + { + for(int bitrate = encTraits->bitrates.size()-1; bitrate >= 0; --bitrate) + { + int ndx = m_CbnSampleFormat.AddString(mpt::String::Format("ABR %i kbit", encTraits->bitrates[bitrate]).c_str()); + m_CbnSampleFormat.SetItemData(ndx, (Encoder::ModeABR<<24) | (encTraits->bitrates[bitrate]<<0)); + if(m_Settings.EncoderSettings.Mode == Encoder::ModeABR && static_cast<int>(m_Settings.EncoderSettings.Bitrate) == encTraits->bitrates[bitrate]) + { + sel = ndx; + } + } + } + if(encTraits->modes & Encoder::ModeCBR) + { + for(int bitrate = encTraits->bitrates.size()-1; bitrate >= 0; --bitrate) + { + int ndx = m_CbnSampleFormat.AddString(mpt::String::Format("CBR %i kbit", encTraits->bitrates[bitrate]).c_str()); + m_CbnSampleFormat.SetItemData(ndx, (Encoder::ModeCBR<<24) | (encTraits->bitrates[bitrate]<<0)); + if(m_Settings.EncoderSettings.Mode == Encoder::ModeCBR && static_cast<int>(m_Settings.EncoderSettings.Bitrate) == encTraits->bitrates[bitrate]) + { + sel = ndx; + } + } + } + if(encTraits->modes & Encoder::ModeEnumerated) + { + for(std::size_t i = 0; i < encTraits->formats.size(); ++i) + { + const Encoder::Format &format = encTraits->formats[i]; + if(format.Samplerate != (int)dwSamplerate || format.Channels != nChannels) + { + continue; + } + if(i > 0xffff) + { + // too may formats + break; + } + int ndx = m_CbnSampleFormat.AddString(format.Description.c_str()); + m_CbnSampleFormat.SetItemData(ndx, i & 0xffff); + if(m_Settings.EncoderSettings.Mode & Encoder::ModeEnumerated && (int)i == encTraits->defaultFormat) + { + sel = ndx; + } else if(m_Settings.EncoderSettings.Mode & Encoder::ModeEnumerated && format.Bitrate > 0 && m_Settings.EncoderSettings.Bitrate == format.Bitrate) + { + sel = ndx; + } + } + } + m_CbnSampleFormat.SetCurSel(sel); +} - UpdateDialog(); - return TRUE; + +void CWaveConvert::OnFileTypeChanged() +//------------------------------------ +{ + DWORD dwFileType = m_CbnFileType.GetItemData(m_CbnFileType.GetCurSel()); + m_Settings.SelectEncoder(dwFileType); + encTraits = m_Settings.GetTraits(); + FillSamplerates(); + FillChannels(); + FillFormats(); + FillTags(); + FillInfo(); } +void CWaveConvert::OnSamplerateChanged() +//-------------------------------------- +{ + //DWORD dwSamplerate = m_CbnSampleRate.GetItemData(m_CbnSampleRate.GetCurSel()); + FillFormats(); +} + + +void CWaveConvert::OnChannelsChanged() +//------------------------------------ +{ + //UINT nChannels = m_CbnChannels.GetItemData(m_CbnChannels.GetCurSel()); + FillFormats(); +} + + void CWaveConvert::OnFormatChanged() //---------------------------------- { - DWORD dwFormat = m_CbnSampleFormat.GetItemData(m_CbnSampleFormat.GetCurSel()); - (void)dwFormat; + //DWORD dwFormat = m_CbnSampleFormat.GetItemData(m_CbnSampleFormat.GetCurSel()); } @@ -328,8 +486,7 @@ m_nMaxOrder = static_cast<ORDERINDEX>(GetDlgItemInt(IDC_EDIT4, NULL, FALSE)); loopCount = static_cast<uint16>(GetDlgItemInt(IDC_EDIT5, NULL, FALSE)); if (m_nMaxOrder < m_nMinOrder) m_bSelectPlay = false; - //m_bHighQuality = IsDlgButtonChecked(IDC_CHECK3) != BST_UNCHECKED; //rewbs.resamplerConf - we don't want this anymore. - m_bNormalize = IsDlgButtonChecked(IDC_CHECK5) != BST_UNCHECKED; + m_Settings.Normalize = IsDlgButtonChecked(IDC_CHECK5) != BST_UNCHECKED; m_bGivePlugsIdleTime = IsDlgButtonChecked(IDC_GIVEPLUGSIDLETIME) != BST_UNCHECKED; if (m_bGivePlugsIdleTime) { @@ -344,295 +501,126 @@ m_bChannelMode = IsDlgButtonChecked(IDC_CHECK4) != BST_UNCHECKED; m_bInstrumentMode= IsDlgButtonChecked(IDC_CHECK6) != BST_UNCHECKED; - // WaveFormatEx + m_Settings.SampleRate = m_CbnSampleRate.GetItemData(m_CbnSampleRate.GetCurSel()); + m_Settings.Channels = (uint16)m_CbnChannels.GetItemData(m_CbnChannels.GetCurSel()); DWORD dwFormat = m_CbnSampleFormat.GetItemData(m_CbnSampleFormat.GetCurSel()); - WaveFormat.Format.wFormatTag = WAVE_FORMAT_PCM; - WaveFormat.Format.nSamplesPerSec = m_CbnSampleRate.GetItemData(m_CbnSampleRate.GetCurSel()); - if (WaveFormat.Format.nSamplesPerSec < 11025) WaveFormat.Format.nSamplesPerSec = 11025; - if (WaveFormat.Format.nSamplesPerSec > 192000) WaveFormat.Format.nSamplesPerSec = 192000; - WaveFormat.Format.nChannels = (WORD)(dwFormat >> 8); - if ((WaveFormat.Format.nChannels != 1) && (WaveFormat.Format.nChannels != 4)) WaveFormat.Format.nChannels = 2; - WaveFormat.Format.wBitsPerSample = (WORD)(dwFormat & 0xFF); - if ((WaveFormat.Format.wBitsPerSample != 8) && (WaveFormat.Format.wBitsPerSample != 24) && (WaveFormat.Format.wBitsPerSample != 32)) WaveFormat.Format.wBitsPerSample = 16; - - WaveFormat.Format.nBlockAlign = (WaveFormat.Format.wBitsPerSample * WaveFormat.Format.nChannels) / 8; - WaveFormat.Format.nAvgBytesPerSec = WaveFormat.Format.nSamplesPerSec * WaveFormat.Format.nBlockAlign; - WaveFormat.Format.cbSize = 0; - // Mono/Stereo 32-bit floating-point - if ((WaveFormat.Format.wBitsPerSample == 32) && (WaveFormat.Format.nChannels <= 2)) + if(encTraits->modes & Encoder::ModeEnumerated) { - WaveFormat.Format.wFormatTag = WAVE_FORMAT_IEEE_FLOAT; + int format = (int)((dwFormat >> 0) & 0xffff); + if(encTraits->formats[format].Sampleformat == SampleFormatInvalid) + { + m_Settings.FinalSampleFormat = SampleFormatFloat32; + } else + { + m_Settings.FinalSampleFormat = encTraits->formats[format].Sampleformat; + } + m_Settings.EncoderSettings.Format = format; + m_Settings.EncoderSettings.Mode = encTraits->defaultMode; + m_Settings.EncoderSettings.Bitrate = encTraits->defaultBitrate; + m_Settings.EncoderSettings.Quality = encTraits->defaultQuality; } else - // MultiChannel configuration - if ((WaveFormat.Format.wBitsPerSample == 32) || (WaveFormat.Format.nChannels > 2)) { - WaveFormat.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; - WaveFormat.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); - WaveFormat.Samples.wValidBitsPerSample = WaveFormat.Format.wBitsPerSample; - switch(WaveFormat.Format.nChannels) - { - case 1: WaveFormat.dwChannelMask = 0x0004; break; // FRONT_CENTER - case 2: WaveFormat.dwChannelMask = 0x0003; break; // FRONT_LEFT | FRONT_RIGHT - case 3: WaveFormat.dwChannelMask = 0x0103; break; // FRONT_LEFT|FRONT_RIGHT|BACK_CENTER - case 4: WaveFormat.dwChannelMask = 0x0033; break; // FRONT_LEFT|FRONT_RIGHT|BACK_LEFT|BACK_RIGHT - default: WaveFormat.dwChannelMask = 0; break; - } - WaveFormat.SubFormat = guid_MEDIASUBTYPE_PCM; + m_Settings.FinalSampleFormat = SampleFormatFloat32; + Encoder::Mode mode = (Encoder::Mode)((dwFormat >> 24) & 0xff); + int quality = (int)((dwFormat >> 0) & 0xff); + int bitrate = (int)((dwFormat >> 0) & 0xffff); + m_Settings.EncoderSettings.Mode = mode; + m_Settings.EncoderSettings.Bitrate = bitrate; + m_Settings.EncoderSettings.Quality = static_cast<float>(quality) * 0.01f; + m_Settings.EncoderSettings.Format = -1; } - CDialog::OnOK(); -} + + { + m_Settings.EncoderSettings.Tags = IsDlgButtonChecked(IDC_CHECK7) ? true : false; -///////////////////////////////////////////////////////////////////////////////////////// -// CLayer3Convert: Converting to MPEG Layer 3 + m_Settings.Tags = FileTags(); -BEGIN_MESSAGE_MAP(CLayer3Convert, CDialog) - ON_COMMAND(IDC_CHECK1, OnCheck1) - ON_COMMAND(IDC_CHECK2, OnCheck2) - ON_CBN_SELCHANGE(IDC_COMBO2, UpdateDialog) -END_MESSAGE_MAP() + if(m_Settings.EncoderSettings.Tags) + { + CString tmp; + m_EditTitle.GetWindowText(tmp); + m_Settings.Tags.title = mpt::String::Decode(tmp.GetString(), mpt::CharsetLocale); -void CLayer3Convert::DoDataExchange(CDataExchange* pDX) -//----------------------------------------------------- -{ - CDialog::DoDataExchange(pDX); - //{{AFX_DATA_MAP(COptionsPlayer) - DDX_Control(pDX, IDC_COMBO1, m_CbnFormat); - DDX_Control(pDX, IDC_COMBO2, m_CbnDriver); - DDX_Control(pDX, IDC_COMBO3, m_CbnGenre); - DDX_Control(pDX, IDC_EDIT3, m_EditAuthor); - DDX_Control(pDX, IDC_EDIT4, m_EditURL); - DDX_Control(pDX, IDC_EDIT5, m_EditAlbum); - DDX_Control(pDX, IDC_EDIT6, m_EditYear); - //}}AFX_DATA_MAP -} + m_EditAuthor.GetWindowText(tmp); + m_Settings.Tags.artist = mpt::String::Decode(tmp.GetString(), mpt::CharsetLocale); + m_EditAlbum.GetWindowText(tmp); + m_Settings.Tags.album = mpt::String::Decode(tmp.GetString(), mpt::CharsetLocale); -BOOL CLayer3Convert::OnInitDialog() -//--------------------------------- -{ - ACMFORMATDETAILS afd; - BYTE wfx[256]; - WAVEFORMATEX *pwfx = (WAVEFORMATEX *)&wfx; - - CDialog::OnInitDialog(); - Drivers[0] = 0; - m_bInitialFound = FALSE; - m_bDriversEnumerated = FALSE; - m_nNumFormats = 0; - m_nNumDrivers = 0; - 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 = (pwfx->nChannels * pwfx->wBitsPerSample) / 8; - pwfx->nAvgBytesPerSec = pwfx->nSamplesPerSec * pwfx->nBlockAlign; - acmConvert.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); - for(size_t iGnr = 0; iGnr < CountOf(id3v1GenreNames); iGnr++) - { - m_CbnGenre.SetItemData(m_CbnGenre.AddString(id3v1GenreNames[iGnr]), iGnr); - } + m_EditURL.GetWindowText(tmp); + m_Settings.Tags.url = mpt::String::Decode(tmp.GetString(), mpt::CharsetLocale); - m_EditYear.SetLimitText(4); - CTime tTime = CTime::GetCurrentTime(); - m_EditYear.SetWindowText(tTime.Format("%Y")); - UpdateDialog(); - return TRUE; -} + m_CbnGenre.GetWindowText(tmp); + m_Settings.Tags.genre = mpt::String::Decode(tmp.GetString(), mpt::CharsetLocale); + m_EditYear.GetWindowText(tmp); + m_Settings.Tags.year = mpt::String::Decode(tmp.GetString(), mpt::CharsetLocale); + if(m_Settings.Tags.year == L"0") + { + m_Settings.Tags.year = std::wstring(); + } -VOID CLayer3Convert::UpdateDialog() -//--------------------------------- -{ - ACMFORMATDETAILS afd; - BYTE wfx[256]; - WAVEFORMATEX *pwfx = (WAVEFORMATEX *)&wfx; - - m_CbnFormat.ResetContent(); - m_nNumFormats = 0; - m_nFormatIndex = 0; - m_nDriverIndex = m_CbnDriver.GetItemData(m_CbnDriver.GetCurSel()); - m_bInitialFound = FALSE; - if (m_nDriverIndex >= m_nNumDrivers) m_nDriverIndex = 0; - MemsetZero(afd); - MemsetZero(wfx); - 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 = pwfx->nChannels * pwfx->wBitsPerSample / 8; - pwfx->nAvgBytesPerSec = pwfx->nSamplesPerSec * pwfx->nBlockAlign; - acmConvert.AcmFormatEnum(NULL, &afd, AcmFormatEnumCB, (DWORD_PTR)this, ACM_FORMATENUMF_CONVERT); - m_CbnFormat.SetCurSel(m_nFormatIndex); -} + if(!m_pSndFile->songMessage.empty()) + { + m_Settings.Tags.comments = mpt::String::Decode(m_pSndFile->songMessage, mpt::CharsetLocale); + } + m_Settings.Tags.bpm = mpt::String::Decode(mpt::String::Format("%d", (int)m_pSndFile->GetCurrentBPM()), mpt::CharsetLocale); -void CLayer3Convert::GetFormat(PMPEGLAYER3WAVEFORMAT pwfx, HACMDRIVERID *phadid) -//------------------------------------------------------------------------------ -{ - *pwfx = Formats[m_nFormatIndex]; - *phadid = Drivers[m_nDriverIndex]; -} + } + } -BOOL CLayer3Convert::AcmFormatEnumCB(HACMDRIVERID hdid, LPACMFORMATDETAILS pafd, DWORD_PTR dwInstance, DWORD fdwSupport) -//---------------------------------------------------------------------------------------------------------------------- -{ - if (dwInstance) - { - CLayer3Convert *that = ((CLayer3Convert *)dwInstance); - if (that->m_bDriversEnumerated) - return ((CLayer3Convert *)dwInstance)->FormatEnumCB(hdid, pafd, fdwSupport); - else - return ((CLayer3Convert *)dwInstance)->DriverEnumCB(hdid, pafd, fdwSupport); - } - return FALSE; + CDialog::OnOK(); } -BOOL CLayer3Convert::DriverEnumCB(HACMDRIVERID hdid, LPACMFORMATDETAILS pafd, DWORD fdwSupport) -//--------------------------------------------------------------------------------------------- +void CWaveConvertSettings::SelectEncoder(std::size_t index) +//--------------------------------------------------------- { - if ((pafd) && (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC) - && (pafd->dwFormatTag == WAVE_FORMAT_MPEGLAYER3) && (m_nNumDrivers < MAX_DRIVERS)) - { - ACMDRIVERDETAILS add; - for (UINT i=0; i<m_nNumDrivers; i++) - { - if (Drivers[i] == hdid) return TRUE; - } - MemsetZero(add); - add.cbStruct = sizeof(add); - if (acmConvert.AcmDriverDetails(hdid, &add, 0L) == MMSYSERR_NOERROR) - { - Drivers[m_nNumDrivers] = hdid; - CHAR *pszName = ((add.szLongName[0]) && (strlen(add.szLongName) < 40)) ? add.szLongName : add.szShortName; - m_CbnDriver.SetItemData( m_CbnDriver.AddString(pszName), m_nNumDrivers); - m_nNumDrivers++; - } - } - return TRUE; + ASSERT(!EncoderFactories.empty()); + ASSERT(index < EncoderFactories.size()); + EncoderIndex = index; + const Encoder::Traits *encTraits = GetTraits(); + EncoderSettings.Mode = encTraits->defaultMode; + EncoderSettings.Bitrate = encTraits->defaultBitrate; + EncoderSettings.Quality = encTraits->defaultQuality; } -BOOL CLayer3Convert::FormatEnumCB(HACMDRIVERID hdid, LPACMFORMATDETAILS pafd, DWORD fdwSupport) -//--------------------------------------------------------------------------------------------- +EncoderFactoryBase *CWaveConvertSettings::GetEncoderFactory() const +//-------------------------------------------------------------- { - if ((pafd) && (fdwSupport & ACMDRIVERDETAILS_SUPPORTF_CODEC) - && (hdid == Drivers[m_nDriverIndex]) - && (pafd->dwFormatTag == WAVE_FORMAT_MPEGLAYER3) && (pafd->pwfx) - && (pafd->cbwfx >= sizeof(MPEGLAYER3WAVEFORMAT)) - && (pafd->pwfx->wFormatTag == WAVE_FORMAT_MPEGLAYER3) - && (pafd->pwfx->cbSize == sizeof(MPEGLAYER3WAVEFORMAT)-sizeof(WAVEFORMATEX)) - && (pafd->pwfx->nSamplesPerSec >= 11025) - && (pafd->pwfx->nChannels >= 1) - && (pafd->pwfx->nChannels <= 2) - && (m_nNumFormats < MAX_FORMATS)) - { - PMPEGLAYER3WAVEFORMAT pmwf = (PMPEGLAYER3WAVEFORMAT)pafd->pwfx; - Formats[m_nNumFormats] = *pmwf; - if ((!m_bInitialFound) && (pmwf->wfx.nSamplesPerSec == 44100) && (pmwf->wfx.nChannels == 2)) - { - m_nFormatIndex = m_nNumFormats; - m_bInitialFound = TRUE; - } - m_CbnFormat.SetItemData( m_CbnFormat.AddString(pafd->szFormat), m_nNumFormats); - m_nNumFormats++; - } - return (m_nNumFormats < MAX_FORMATS) ? TRUE : FALSE; + ASSERT(!EncoderFactories.empty()); + return EncoderFactories[EncoderIndex]; } -void CLayer3Convert::OnCheck1() -//----------------------------- +const Encoder::Traits *CWaveConvertSettings::GetTraits() const +//------------------------------------------------------------ { - if (IsDlgButtonChecked(IDC_CHECK1)) - { - m_dwFileLimit = GetDlgItemInt(IDC_EDIT1, NULL, FALSE); - if (!m_dwFileLimit) - { - m_dwFileLimit = 1000; - SetDlgItemText(IDC_EDIT1, "1000"); - } - } else m_dwFileLimit = 0; + ASSERT(!EncoderFactories.empty()); + return &EncoderFactories[EncoderIndex]->GetTraits(); } -void CLayer3Convert::OnCheck2() -//----------------------------- +CWaveConvertSettings::CWaveConvertSettings(std::size_t defaultEncoder, const std::vector<EncoderFactoryBase*> &encFactories) +//-------------------------------------------------------------------------------------------------------------------------- + : EncoderFactories(encFactories) + , EncoderIndex(defaultEncoder) + , Normalize(false) + , SampleRate(44100) + , Channels(2) + , FinalSampleFormat(SampleFormatInt16) + , EncoderSettings(true, Encoder::ModeCBR, 256, 0.8f, -1) { - if (IsDlgButtonChecked(IDC_CHECK2)) - { - m_dwSongLimit = GetDlgItemInt(IDC_EDIT2, NULL, FALSE); - if (!m_dwSongLimit) - { - m_dwSongLimit = 600; - SetDlgItemText(IDC_EDIT2, "600"); - } - } else m_dwSongLimit = 0; + SelectEncoder(EncoderIndex); } -void CLayer3Convert::OnOK() -//------------------------- -{ - CHAR sText[256] = ""; - - if (m_dwFileLimit) m_dwFileLimit = GetDlgItemInt(IDC_EDIT1, NULL, FALSE); - if (m_dwSongLimit) m_dwSongLimit = GetDlgItemInt(IDC_EDIT2, NULL, FALSE); - m_nFormatIndex = m_CbnFormat.GetItemData(m_CbnFormat.GetCurSel()); - m_nDriverIndex = m_CbnDriver.GetItemData(m_CbnDriver.GetCurSel()); - m_bSaveInfoField = IsDlgButtonChecked(IDC_CHECK3); - - m_FileTags.title = m_pSndFile->GetTitle(); - - m_EditAuthor.GetWindowText(sText, sizeof(sText)); - m_FileTags.artist = sText; - - m_EditURL.GetWindowText(sText, sizeof(sText)); - m_FileTags.url = sText; - - m_EditAlbum.GetWindowText(sText, sizeof(sText)); - m_FileTags.album = sText; - - m_EditYear.GetWindowText(sText, MIN(5, sizeof(sText))); - m_FileTags.year = sText; - if(m_FileTags.year == "0") - m_FileTags.year = ""; - - m_CbnGenre.GetWindowText(sText, sizeof(sText)); - m_FileTags.genre = sText; - - if(!m_pSndFile->songMessage.empty()) - { - m_FileTags.comments = m_pSndFile->songMessage.GetFormatted(SongMessage::leLF); - } - else - { - m_FileTags.comments = ""; - } - - wsprintf(sText, "%d", (int)m_pSndFile->GetCurrentBPM()); - m_FileTags.bpm = sText; - - CDialog::OnOK(); -} - ///////////////////////////////////////////////////////////////////////////////////////// // CDoWaveConvert: save a mod as a wave file @@ -650,15 +638,13 @@ } -#define WAVECONVERTBUFSIZE MIXBUFFERSIZE //Going over MIXBUFFERSIZE can kill VSTPlugs - - void CDoWaveConvert::OnButton1() //------------------------------ { static char buffer[MIXBUFFERSIZE * 4 * 4]; // channels * sizeof(biggestsample) static float floatbuffer[MIXBUFFERSIZE ... [truncated message content] |