From: <sag...@us...> - 2010-09-30 22:44:40
|
Revision: 728 http://modplug.svn.sourceforge.net/modplug/?rev=728&view=rev Author: saga-games Date: 2010-09-30 22:44:28 +0000 (Thu, 30 Sep 2010) Log Message: ----------- [New] WAV Export: Sample-exact cue points are now written for each pattern transition (as requested by Skaven). TODO: Make this feature optional. [Ref] Moved WAV structs and IFF chunk ID stuff to a separate file [Mod] OpenMPT: Version is now 1.19.00.06 Modified Paths: -------------- trunk/OpenMPT/mptrack/Mod2wave.cpp trunk/OpenMPT/mptrack/View_smp.cpp trunk/OpenMPT/mptrack/mod2midi.cpp trunk/OpenMPT/mptrack/mptrack.vcproj trunk/OpenMPT/mptrack/mptrack_08.vcproj trunk/OpenMPT/mptrack/tagging.h trunk/OpenMPT/mptrack/version.h trunk/OpenMPT/soundlib/Dlsbank.cpp trunk/OpenMPT/soundlib/Load_mid.cpp trunk/OpenMPT/soundlib/Load_wav.cpp trunk/OpenMPT/soundlib/Sampleio.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/Sndmix.cpp Added Paths: ----------- trunk/OpenMPT/soundlib/Wav.h Modified: trunk/OpenMPT/mptrack/Mod2wave.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mod2wave.cpp 2010-09-29 23:28:20 UTC (rev 727) +++ trunk/OpenMPT/mptrack/Mod2wave.cpp 2010-09-30 22:44:28 UTC (rev 728) @@ -6,6 +6,7 @@ #include "mpdlgs.h" #include "vstplug.h" #include "mod2wave.h" +#include "Wav.h" extern UINT nMixingRates[NUMMIXRATE]; extern LPCSTR gszChnCfgNames[3]; @@ -696,6 +697,9 @@ ::SendMessage(progress, PBM_SETRANGE, 0, MAKELPARAM(0, (DWORD)(max >> 14))); } + // No pattern cue points yet + m_pSndFile->m_PatternCuePoints.clear(); + // Process the conversion UINT nBytesPerSample = (CSoundFile::gnBitsPerSample * CSoundFile::gnChannels) / 8; // For calculating the remaining time @@ -707,6 +711,20 @@ for (UINT n=0; ; n++) { UINT lRead = m_pSndFile->Read(buffer, sizeof(buffer)); + + // Process cue points (add base offset), if there are any to process. + vector<PatternCuePoint>::reverse_iterator iter = m_pSndFile->m_PatternCuePoints.rbegin(); + for(iter = m_pSndFile->m_PatternCuePoints.rbegin(); iter != m_pSndFile->m_PatternCuePoints.rend(); ++iter) + { + if(iter->processed) + { + // From this point, all cues have already been processed. + break; + } + iter->offset += ullSamples; + iter->processed = true; + } + /* if (m_bGivePlugsIdleTime) { LARGE_INTEGER startTime, endTime, duration,Freq; QueryPerformanceFrequency(&Freq); @@ -834,7 +852,37 @@ } } } - header.filesize = (sizeof(WAVEFILEHEADER)-8) + (8+fmthdr.length) + (8+datahdr.length); + + // Write cue points + DWORD cuePointLength = 0; + if(m_pSndFile->m_PatternCuePoints.size() > 0) + { + WAVCUEHEADER cuehdr; + cuehdr.cue_id = LittleEndian(IFFID_cue); + cuehdr.cue_num = m_pSndFile->m_PatternCuePoints.size(); + cuehdr.cue_len = 4 + cuehdr.cue_num * sizeof(WAVCUEPOINT); + cuePointLength = 8 + cuehdr.cue_len; + cuehdr.cue_num = LittleEndian(cuehdr.cue_num); + cuehdr.cue_len = LittleEndian(cuehdr.cue_len); + fwrite(&cuehdr, 1, sizeof(WAVCUEHEADER), f); + + // Write all cue points + vector<PatternCuePoint>::iterator iter; + DWORD num = 0; + for(iter = m_pSndFile->m_PatternCuePoints.begin(); iter != m_pSndFile->m_PatternCuePoints.end(); ++iter) + { + WAVCUEPOINT cuepoint; + cuepoint.cp_id = LittleEndian(num++); + cuepoint.cp_pos = LittleEndian((DWORD)iter->offset); + cuepoint.cp_chunkid = LittleEndian(IFFID_data); + cuepoint.cp_chunkstart = 0; // we use no Wave List Chunk (wavl) as we have only one data block, so this should be 0. + cuepoint.cp_blockstart = 0; + cuepoint.cp_offset = LittleEndian((DWORD)iter->offset); + fwrite(&cuepoint, 1, sizeof(WAVCUEPOINT), f); + } + } + + header.filesize = (sizeof(WAVEFILEHEADER) - 8) + (8 + fmthdr.length) + (8 + datahdr.length) + (cuePointLength); fseek(f, 0, SEEK_SET); fwrite(&header, sizeof(header), 1, f); fseek(f, dwDataOffset-sizeof(datahdr), SEEK_SET); Modified: trunk/OpenMPT/mptrack/View_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_smp.cpp 2010-09-29 23:28:20 UTC (rev 727) +++ trunk/OpenMPT/mptrack/View_smp.cpp 2010-09-30 22:44:28 UTC (rev 728) @@ -11,6 +11,7 @@ #include "midi.h" #include "dlg_misc.h" #include "modsmp_ctrl.h" +#include "Wav.h" #define new DEBUG_NEW Modified: trunk/OpenMPT/mptrack/mod2midi.cpp =================================================================== --- trunk/OpenMPT/mptrack/mod2midi.cpp 2010-09-29 23:28:20 UTC (rev 727) +++ trunk/OpenMPT/mptrack/mod2midi.cpp 2010-09-30 22:44:28 UTC (rev 728) @@ -1,6 +1,7 @@ #include "stdafx.h" #include "mptrack.h" #include "mod2midi.h" +#include "Wav.h" #pragma pack(1) Modified: trunk/OpenMPT/mptrack/mptrack.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack.vcproj 2010-09-29 23:28:20 UTC (rev 727) +++ trunk/OpenMPT/mptrack/mptrack.vcproj 2010-09-30 22:44:28 UTC (rev 728) @@ -942,6 +942,9 @@ RelativePath=".\vstplug.h"> </File> <File + RelativePath="..\soundlib\Wav.h"> + </File> + <File RelativePath="..\soundlib\wavConverter.h"> </File> <File Modified: trunk/OpenMPT/mptrack/mptrack_08.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack_08.vcproj 2010-09-29 23:28:20 UTC (rev 727) +++ trunk/OpenMPT/mptrack/mptrack_08.vcproj 2010-09-30 22:44:28 UTC (rev 728) @@ -1251,6 +1251,10 @@ > </File> <File + RelativePath="..\soundlib\Wav.h" + > + </File> + <File RelativePath="..\soundlib\wavConverter.h" > </File> Modified: trunk/OpenMPT/mptrack/tagging.h =================================================================== --- trunk/OpenMPT/mptrack/tagging.h 2010-09-29 23:28:20 UTC (rev 727) +++ trunk/OpenMPT/mptrack/tagging.h 2010-09-30 22:44:28 UTC (rev 728) @@ -2,6 +2,7 @@ // ID3v2.4 / etc. tagging class (for mp3 / wav / etc. support) #include <string> +#include "Wav.h" using std::string; Modified: trunk/OpenMPT/mptrack/version.h =================================================================== --- trunk/OpenMPT/mptrack/version.h 2010-09-29 23:28:20 UTC (rev 727) +++ trunk/OpenMPT/mptrack/version.h 2010-09-30 22:44:28 UTC (rev 728) @@ -15,7 +15,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 19 #define VER_MINOR 00 -#define VER_MINORMINOR 05 +#define VER_MINORMINOR 06 //Creates version number from version parts that appears in version string. //For example MAKE_VERSION_NUMERIC(1,17,02,28) gives version number of Modified: trunk/OpenMPT/soundlib/Dlsbank.cpp =================================================================== --- trunk/OpenMPT/soundlib/Dlsbank.cpp 2010-09-29 23:28:20 UTC (rev 727) +++ trunk/OpenMPT/soundlib/Dlsbank.cpp 2010-09-30 22:44:28 UTC (rev 728) @@ -16,7 +16,9 @@ #include "sndfile.h" #include "../mptrack/mptrack.h" #include "dlsbank.h" +#include "Wav.h" + //#define DLSBANK_LOG //#define DLSINSTR_LOG Modified: trunk/OpenMPT/soundlib/Load_mid.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mid.cpp 2010-09-29 23:28:20 UTC (rev 727) +++ trunk/OpenMPT/soundlib/Load_mid.cpp 2010-09-30 22:44:28 UTC (rev 728) @@ -13,7 +13,9 @@ #include "stdafx.h" #include "Loaders.h" #include "dlsbank.h" +#include "Wav.h" + #pragma warning(disable:4244) //#define MIDI_LOG Modified: trunk/OpenMPT/soundlib/Load_wav.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_wav.cpp 2010-09-29 23:28:20 UTC (rev 727) +++ trunk/OpenMPT/soundlib/Load_wav.cpp 2010-09-30 22:44:28 UTC (rev 728) @@ -9,6 +9,7 @@ #include "stdafx.h" #include "Loaders.h" +#include "Wav.h" #ifndef WAVE_FORMAT_EXTENSIBLE #define WAVE_FORMAT_EXTENSIBLE 0xFFFE Modified: trunk/OpenMPT/soundlib/Sampleio.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sampleio.cpp 2010-09-29 23:28:20 UTC (rev 727) +++ trunk/OpenMPT/soundlib/Sampleio.cpp 2010-09-30 22:44:28 UTC (rev 728) @@ -11,6 +11,7 @@ #include "sndfile.h" #include "it_defs.h" #include "wavConverter.h" +#include "Wav.h" #pragma warning(disable:4244) Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2010-09-29 23:28:20 UTC (rev 727) +++ trunk/OpenMPT/soundlib/Sndfile.h 2010-09-30 22:44:28 UTC (rev 728) @@ -462,6 +462,15 @@ }; +// For WAV export (writing pattern positions to file) +struct PatternCuePoint +{ + bool processed; // has this point been processed by the main WAV render function yet? + ULONGLONG offset; // offset in the file (in samples) + ORDERINDEX order; // which order is this? +}; + + class CSoundFile; @@ -599,8 +608,8 @@ UINT m_nMaxOrderPosition, m_nPatternNames; LPSTR m_lpszSongComments, m_lpszPatternNames; UINT ChnMix[MAX_CHANNELS]; // Channels to be mixed - MODCHANNEL Chn[MAX_CHANNELS]; // Channels - MODCHANNELSETTINGS ChnSettings[MAX_BASECHANNELS]; // Channels settings + MODCHANNEL Chn[MAX_CHANNELS]; // Mixing channels + MODCHANNELSETTINGS ChnSettings[MAX_BASECHANNELS]; // Initial channels settings CPatternContainer Patterns; // Patterns ModSequenceSet Order; // Modsequences. Order[x] returns an index of a pattern located at order x of the current sequence. MODSAMPLE Samples[MAX_SAMPLES]; // Sample Headers @@ -617,6 +626,8 @@ DWORD m_dwCreatedWithVersion; DWORD m_dwLastSavedWithVersion; + vector<PatternCuePoint> m_PatternCuePoints; // For WAV export (writing pattern positions to file) + // -> CODE#0023 // -> DESC="IT project files (.itp)" CHAR m_szInstrumentPath[MAX_INSTRUMENTS][_MAX_PATH]; @@ -1048,127 +1059,6 @@ } -////////////////////////////////////////////////////////// -// WAVE format information - -#pragma pack(1) - -// Standard IFF chunks IDs -#define IFFID_FORM 0x4d524f46 -#define IFFID_RIFF 0x46464952 -#define IFFID_WAVE 0x45564157 -#define IFFID_LIST 0x5453494C -#define IFFID_INFO 0x4F464E49 - -// IFF Info fields -#define IFFID_ICOP 0x504F4349 -#define IFFID_IART 0x54524149 -#define IFFID_IPRD 0x44525049 -#define IFFID_INAM 0x4D414E49 -#define IFFID_ICMT 0x544D4349 -#define IFFID_IENG 0x474E4549 -#define IFFID_ISFT 0x54465349 -#define IFFID_ISBJ 0x4A425349 -#define IFFID_IGNR 0x524E4749 -#define IFFID_ICRD 0x44524349 - -// Wave IFF chunks IDs -#define IFFID_wave 0x65766177 -#define IFFID_fmt 0x20746D66 -#define IFFID_wsmp 0x706D7377 -#define IFFID_pcm 0x206d6370 -#define IFFID_data 0x61746164 -#define IFFID_smpl 0x6C706D73 -#define IFFID_xtra 0x61727478 - -typedef struct WAVEFILEHEADER -{ - DWORD id_RIFF; // "RIFF" - DWORD filesize; // file length-8 - DWORD id_WAVE; -} WAVEFILEHEADER; - - -typedef struct WAVEFORMATHEADER -{ - DWORD id_fmt; // "fmt " - DWORD hdrlen; // 16 - WORD format; // 1 - WORD channels; // 1:mono, 2:stereo - DWORD freqHz; // sampling freq - DWORD bytessec; // bytes/sec=freqHz*samplesize - WORD samplesize; // sizeof(sample) - WORD bitspersample; // bits per sample (8/16) -} WAVEFORMATHEADER; - - -typedef struct WAVEDATAHEADER -{ - DWORD id_data; // "data" - DWORD length; // length of data -} WAVEDATAHEADER; - - -typedef struct WAVESMPLHEADER -{ - // SMPL - DWORD smpl_id; // "smpl" -> 0x6C706D73 - DWORD smpl_len; // length of smpl: 3Ch (54h with sustain loop) - DWORD dwManufacturer; - DWORD dwProduct; - DWORD dwSamplePeriod; // 1000000000/freqHz - DWORD dwBaseNote; // 3Ch = C-4 -> 60 + RelativeTone - DWORD dwPitchFraction; - DWORD dwSMPTEFormat; - DWORD dwSMPTEOffset; - DWORD dwSampleLoops; // number of loops - DWORD cbSamplerData; -} WAVESMPLHEADER; - - -typedef struct SAMPLELOOPSTRUCT -{ - DWORD dwIdentifier; - DWORD dwLoopType; // 0=normal, 1=bidi - DWORD dwLoopStart; - DWORD dwLoopEnd; // Byte offset ? - DWORD dwFraction; - DWORD dwPlayCount; // Loop Count, 0=infinite -} SAMPLELOOPSTRUCT; - - -typedef struct WAVESAMPLERINFO -{ - WAVESMPLHEADER wsiHdr; - SAMPLELOOPSTRUCT wsiLoops[2]; -} WAVESAMPLERINFO; - - -typedef struct WAVELISTHEADER -{ - DWORD list_id; // "LIST" -> 0x5453494C - DWORD list_len; - DWORD info; // "INFO" -} WAVELISTHEADER; - - -typedef struct WAVEEXTRAHEADER -{ - DWORD xtra_id; // "xtra" -> 0x61727478 - DWORD xtra_len; - DWORD dwFlags; - WORD wPan; - WORD wVolume; - WORD wGlobalVol; - WORD wReserved; - BYTE nVibType; - BYTE nVibSweep; - BYTE nVibDepth; - BYTE nVibRate; -} WAVEEXTRAHEADER; - -#pragma pack() - /////////////////////////////////////////////////////////// // Low-level Mixing functions Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2010-09-29 23:28:20 UTC (rev 727) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2010-09-30 22:44:28 UTC (rev 728) @@ -312,8 +312,19 @@ m_nBufferCount = lRead; } else #endif - if (!ReadNote()) + if (ReadNote()) { + // Save pattern cue points for WAV rendering here (if we reached a new pattern, that is.) + if(m_bIsRendering && (m_PatternCuePoints.empty() || m_nCurrentPattern != m_PatternCuePoints.back().order)) + { + PatternCuePoint cue; + cue.offset = lMax - lRead; + cue.order = m_nCurrentPattern; + cue.processed = false; + m_PatternCuePoints.push_back(cue); + } + } else + { #ifdef MODPLUG_TRACKER if ((m_nMaxOrderPosition) && (m_nCurrentPattern >= m_nMaxOrderPosition)) { Added: trunk/OpenMPT/soundlib/Wav.h =================================================================== --- trunk/OpenMPT/soundlib/Wav.h (rev 0) +++ trunk/OpenMPT/soundlib/Wav.h 2010-09-30 22:44:28 UTC (rev 728) @@ -0,0 +1,154 @@ +/* + * Wav.h + * ----- + * Purpose: Headers for WAV reading / writing (WAV structs, FOURCCs, etc...) + * Notes : Some FOURCCs are also used by the MIDI/DLS routines. + * Authors: OpenMPT Devs + * + */ + +#ifndef WAV_H +#define WAV_H +#pragma once + +#pragma pack(1) + +// Standard IFF chunks IDs +#define IFFID_FORM 0x4d524f46 +#define IFFID_RIFF 0x46464952 +#define IFFID_WAVE 0x45564157 +#define IFFID_LIST 0x5453494C +#define IFFID_INFO 0x4F464E49 + +// IFF Info fields +#define IFFID_ICOP 0x504F4349 +#define IFFID_IART 0x54524149 +#define IFFID_IPRD 0x44525049 +#define IFFID_INAM 0x4D414E49 +#define IFFID_ICMT 0x544D4349 +#define IFFID_IENG 0x474E4549 +#define IFFID_ISFT 0x54465349 +#define IFFID_ISBJ 0x4A425349 +#define IFFID_IGNR 0x524E4749 +#define IFFID_ICRD 0x44524349 + +// Wave IFF chunks IDs +#define IFFID_wave 0x65766177 +#define IFFID_fmt 0x20746D66 +#define IFFID_wsmp 0x706D7377 +#define IFFID_pcm 0x206d6370 +#define IFFID_data 0x61746164 +#define IFFID_smpl 0x6C706D73 +#define IFFID_xtra 0x61727478 +#define IFFID_cue 0x20657563 + + +typedef struct WAVEFILEHEADER +{ + DWORD id_RIFF; // "RIFF" + DWORD filesize; // file length-8 + DWORD id_WAVE; +} WAVEFILEHEADER; + + +typedef struct WAVEFORMATHEADER +{ + DWORD id_fmt; // "fmt " + DWORD hdrlen; // 16 + WORD format; // 1 + WORD channels; // 1:mono, 2:stereo + DWORD freqHz; // sampling freq + DWORD bytessec; // bytes/sec=freqHz*samplesize + WORD samplesize; // sizeof(sample) + WORD bitspersample; // bits per sample (8/16) +} WAVEFORMATHEADER; + + +typedef struct WAVEDATAHEADER +{ + DWORD id_data; // "data" + DWORD length; // length of data +} WAVEDATAHEADER; + + +typedef struct WAVESMPLHEADER +{ + // SMPL + DWORD smpl_id; // "smpl" -> 0x6C706D73 + DWORD smpl_len; // length of smpl: 3Ch (54h with sustain loop) + DWORD dwManufacturer; + DWORD dwProduct; + DWORD dwSamplePeriod; // 1000000000/freqHz + DWORD dwBaseNote; // 3Ch = C-4 -> 60 + RelativeTone + DWORD dwPitchFraction; + DWORD dwSMPTEFormat; + DWORD dwSMPTEOffset; + DWORD dwSampleLoops; // number of loops + DWORD cbSamplerData; +} WAVESMPLHEADER; + + +typedef struct SAMPLELOOPSTRUCT +{ + DWORD dwIdentifier; + DWORD dwLoopType; // 0=normal, 1=bidi + DWORD dwLoopStart; + DWORD dwLoopEnd; // Byte offset ? + DWORD dwFraction; + DWORD dwPlayCount; // Loop Count, 0=infinite +} SAMPLELOOPSTRUCT; + + +typedef struct WAVESAMPLERINFO +{ + WAVESMPLHEADER wsiHdr; + SAMPLELOOPSTRUCT wsiLoops[2]; +} WAVESAMPLERINFO; + + +typedef struct WAVELISTHEADER +{ + DWORD list_id; // "LIST" -> 0x5453494C + DWORD list_len; + DWORD info; // "INFO" +} WAVELISTHEADER; + + +typedef struct WAVEEXTRAHEADER +{ + DWORD xtra_id; // "xtra" -> 0x61727478 + DWORD xtra_len; + DWORD dwFlags; + WORD wPan; + WORD wVolume; + WORD wGlobalVol; + WORD wReserved; + BYTE nVibType; + BYTE nVibSweep; + BYTE nVibDepth; + BYTE nVibRate; +} WAVEEXTRAHEADER; + + +typedef struct WAVCUEHEADER +{ + DWORD cue_id; // "cue " -> 0x20657563 + DWORD cue_len; + DWORD cue_num; +} WAVCUEHEADER; + + +typedef struct WAVCUEPOINT +{ + DWORD cp_id; // Unique identification value + DWORD cp_pos; // Play order position + DWORD cp_chunkid; // RIFF ID of corresponding data chunk + DWORD cp_chunkstart; // Byte Offset of Data Chunk + DWORD cp_blockstart; // Byte Offset to sample of First Channel + DWORD cp_offset; // Byte Offset to sample byte of First Channel +} WAVCUEPOINT; + + +#pragma pack() + +#endif // WAV_H \ No newline at end of file This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |