From: <rel...@us...> - 2008-09-07 22:14:02
|
Revision: 223 http://modplug.svn.sourceforge.net/modplug/?rev=223&view=rev Author: relabsoluness Date: 2008-09-07 22:13:53 +0000 (Sun, 07 Sep 2008) Log Message: ----------- ./ Name changes and update fixes to plugin velocity/volume handling controls in instrument tab. . Further fixes to ReadSample/itp vulnerabilities. (http://secunia.com/advisories/21418/) . Fix to possible crash in LOAD_AMF.CPP. . Fixed wrong default velocity/volume handling when loading XM files. ? Deleted miscellaneous items from version control. ? Removed GPL notifications from soundlib files. - pitch shift/time stretch is gone. Can be enabled by disabling definition NO_XSOUNDLIB and adding xsoundlib.lib to linking. Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_ins.cpp trunk/OpenMPT/mptrack/Ctrl_smp.cpp trunk/OpenMPT/mptrack/Ctrl_smp.h trunk/OpenMPT/mptrack/MPTRACK.sln trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/mptrack/mptrack.vcproj trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/soundlib/Dlsbank.cpp trunk/OpenMPT/soundlib/Fastmix.cpp trunk/OpenMPT/soundlib/LOAD_AMF.CPP trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_mid.cpp trunk/OpenMPT/soundlib/Load_xm.cpp trunk/OpenMPT/soundlib/Mmcmp.cpp trunk/OpenMPT/soundlib/Mmx_mix.cpp trunk/OpenMPT/soundlib/Sampleio.cpp trunk/OpenMPT/soundlib/Snd_dsp.cpp trunk/OpenMPT/soundlib/Snd_eq.cpp trunk/OpenMPT/soundlib/Snd_flt.cpp trunk/OpenMPT/soundlib/Snd_fx.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/Sndmix.cpp trunk/OpenMPT/soundlib/Tables.cpp trunk/OpenMPT/soundlib/Waveform.cpp Removed Paths: ------------- trunk/OpenMPT/mptrack/Debug/ trunk/OpenMPT/mptrack/bin/getVersionFromCode.pl trunk/OpenMPT/mptrack/bin/version Modified: trunk/OpenMPT/mptrack/Ctrl_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/mptrack/Ctrl_ins.cpp 2008-09-07 22:13:53 UTC (rev 223) @@ -805,7 +805,7 @@ m_CbnFilterMode.SetItemData(m_CbnFilterMode.AddString("Force highpass"), FLTMODE_HIGHPASS); //VST velocity/volume handling - m_CbnPluginVelocityHandling.AddString("Use channelvolume"); + m_CbnPluginVelocityHandling.AddString("Use note volume"); m_CbnPluginVelocityHandling.AddString("Process as volume"); m_CbnPluginVolumeHandling.AddString("MIDI volume"); m_CbnPluginVolumeHandling.AddString("Dry/Wet ratio"); @@ -1177,6 +1177,21 @@ CheckDlgButton(IDC_CHECK_PITCHTEMPOLOCK, MF_UNCHECKED); OnBnClickedCheckPitchtempolock(); + + if(m_pSndFile->GetType() & (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT)) + { + if(m_CbnMixPlug.GetCurSel() > 0 && m_pSndFile->GetModFlag(MSF_MIDICC_BUGEMULATION) == false) + { + m_CbnPluginVelocityHandling.EnableWindow(TRUE); + m_CbnPluginVolumeHandling.EnableWindow(TRUE); + } + else + { + m_CbnPluginVelocityHandling.EnableWindow(FALSE); + m_CbnPluginVolumeHandling.EnableWindow(FALSE); + } + + } } else { m_EditName.SetWindowText(""); Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2008-09-07 22:13:53 UTC (rev 223) @@ -10,10 +10,10 @@ #include "PSRatioCalc.h" //rewbs.timeStretchMods #include "mpdlgs.h" -// -> CODE#0029 -// -> DESC="pitch shifting - time stretching" -#include "smbPitchShift.h" -#include "samplerate.h" +#ifndef NO_XSOUNDLIB + #include "smbPitchShift.h" + #include "samplerate.h" +#endif #ifdef _DEBUG #include <math.h> @@ -65,14 +65,13 @@ ON_COMMAND(ID_PREVINSTRUMENT, OnPrevInstrument) ON_COMMAND(ID_NEXTINSTRUMENT, OnNextInstrument) -// -> CODE#0029 -// -> DESC="pitch shifting - time stretching" +#ifndef NO_XSOUNDLIB ON_COMMAND(IDC_BUTTON1, OnPitchShiftTimeStretch) ON_COMMAND(IDC_BUTTON2, OnEstimateSampleSize) ON_COMMAND(IDC_BUTTON3, OnPitchShiftTimeStretchAccept) ON_COMMAND(IDC_BUTTON4, OnPitchShiftTimeStretchCancel) ON_COMMAND(IDC_CHECK3, OnEnableStretchToSize) -// -! TEST#0029 +#endif ON_EN_CHANGE(IDC_SAMPLE_NAME, OnNameChanged) ON_EN_CHANGE(IDC_SAMPLE_FILENAME, OnFileNameChanged) @@ -140,13 +139,12 @@ DDX_Control(pDX, IDC_EDIT15, m_EditVibDepth); DDX_Control(pDX, IDC_EDIT16, m_EditVibRate); -// -> CODE#0029 -// -> DESC="pitch shifting - time stretching" +#ifndef NO_XSOUNDLIB DDX_Control(pDX, IDC_COMBO4, m_ComboPitch); DDX_Control(pDX, IDC_COMBO5, m_ComboQuality); DDX_Control(pDX, IDC_COMBO6, m_ComboFFT); DDX_Text(pDX, IDC_EDIT6, m_dTimeStretchRatio); //rewbs.timeStretchMods -// -! TEST#0029 +#endif //}}AFX_DATA_MAP } @@ -158,25 +156,25 @@ m_nSample = 1; m_nLockCount = 1; -// -> CODE#0029 -// -> DESC="pitch shifting - time stretching" +#ifndef NO_XSOUNDLIB pSampleUndoBuffer = NULL; UndoBufferSize = 0; -// -! TEST#0029 +#endif + } -// -> CODE#0029 -// -> DESC="pitch shifting - time stretching" -CCtrlSamples::~CCtrlSamples() -{ - if(pSampleUndoBuffer) CSoundFile::FreeSample(pSampleUndoBuffer); - pSampleUndoBuffer = NULL; - UndoBufferSize = 0; -} -// -! TEST#0029 +#ifndef NO_XSOUNDLIB + CCtrlSamples::~CCtrlSamples() + { + if(pSampleUndoBuffer) CSoundFile::FreeSample(pSampleUndoBuffer); + pSampleUndoBuffer = NULL; + UndoBufferSize = 0; + } +#endif + CRuntimeClass *CCtrlSamples::GetAssociatedViewClass() //--------------------------------------------------- { @@ -242,8 +240,28 @@ m_CbnBaseNote.AddString(s); } -// -> CODE#0029 -// -> DESC="pitch shifting - time stretching" + +#ifndef NO_XSOUNDLIB + m_ComboFFT.ShowWindow(SW_SHOW); + m_ComboPitch.ShowWindow(SW_SHOW); + m_ComboQuality.ShowWindow(SW_SHOW); + m_ComboFFT.ShowWindow(SW_SHOW); + + GetDlgItem(IDC_BUTTON1)->ShowWindow(SW_SHOW); // PitchShiftTimeStretch + GetDlgItem(IDC_BUTTON2)->ShowWindow(SW_SHOW); // EstimateSampleSize + GetDlgItem(IDC_BUTTON3)->ShowWindow(SW_SHOW); // PitchShiftTimeStretchAccept + GetDlgItem(IDC_BUTTON4)->ShowWindow(SW_SHOW); // PitchShiftTimeStretchCancel + GetDlgItem(IDC_CHECK2)->ShowWindow(SW_SHOW); // Preview mode + GetDlgItem(IDC_CHECK3)->ShowWindow(SW_SHOW); // EnableStretchToSize + GetDlgItem(IDC_EDIT6)->ShowWindow(SW_SHOW); // + GetDlgItem(IDC_GROUPBOX_PITCH_TIME)->ShowWindow(SW_SHOW); // + GetDlgItem(IDC_TEXT_PITCH)->ShowWindow(SW_SHOW); // + GetDlgItem(IDC_TEXT_QUALITY)->ShowWindow(SW_SHOW); // + GetDlgItem(IDC_TEXT_FFT)->ShowWindow(SW_SHOW); // + GetDlgItem(IDC_TEXT_PREVIEW)->ShowWindow(SW_SHOW); // + GetDlgItem(IDC_GROUPBOX_PITCH_TIME)->ShowWindow(SW_SHOW); // + GetDlgItem(IDC_TEXT_PERCENT)->ShowWindow(SW_SHOW); // + CHAR str[16]; // Pitch selection @@ -297,7 +315,7 @@ // Stretch to size check box OnEnableStretchToSize(); -// -! TEST#0029 +#endif // NO_XSOUNDLIB return TRUE; } @@ -319,10 +337,9 @@ if (pSndFile->m_nSamples < 1) pSndFile->m_nSamples = 1; if ((nSmp < 1) || (nSmp > pSndFile->m_nSamples)) return FALSE; -// -> CODE#0029 -// -> DESC="pitch shifting - time stretching" +#ifndef NO_XSOUNDLIB if(pSampleUndoBuffer) OnPitchShiftTimeStretchCancel(); -// -! TEST#0029 +#endif LockControls(); if (m_nSample != nSmp) @@ -666,11 +683,11 @@ DWORD len; BOOL bOk; -// -> CODE#0029 -// -> DESC="pitch shifting - time stretching" +#ifndef NO_XSOUNDLIB if(pSampleUndoBuffer) OnPitchShiftTimeStretchCancel(); -// -! TEST#0029 +#endif + BeginWaitCursor(); if ((!lpszFileName) || (!f.Open(lpszFileName))) { @@ -786,11 +803,11 @@ { if ((!pSndFile) || (!nSample) || (nSample > pSndFile->m_nSamples)) return FALSE; -// -> CODE#0029 -// -> DESC="pitch shifting - time stretching" +#ifndef NO_XSOUNDLIB if(pSampleUndoBuffer) OnPitchShiftTimeStretchCancel(); -// -! TEST#0029 +#endif + BeginWaitCursor(); BEGIN_CRITICAL(); m_pSndFile->DestroySample(m_nSample); @@ -819,10 +836,9 @@ if ((!IsLocked()) && (m_pSndFile)) { -// -> CODE#0029 -// -> DESC="pitch shifting - time stretching" +#ifndef NO_XSOUNDLIB if(pSampleUndoBuffer) OnPitchShiftTimeStretchCancel(); -// -! TEST#0029 +#endif UINT n = GetDlgItemInt(IDC_EDIT_SAMPLE); if ((n > 0) && (n <= m_pSndFile->m_nSamples) && (n != m_nSample)) @@ -863,10 +879,9 @@ if (smp > 0) { -// -> CODE#0029 -// -> DESC="pitch shifting - time stretching" + #ifndef NO_XSOUNDLIB if(pSampleUndoBuffer) OnPitchShiftTimeStretchCancel(); -// -! TEST#0029 + #endif CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); SetCurrentSample(smp); @@ -1416,8 +1431,7 @@ } -// -> CODE#0029 -// -> DESC="pitch shifting - time stretching" +#ifndef NO_XSOUNDLIB #define MAX_BUFFER_LENGTH 8192 #define CLIP_SOUND(v) v = v < -1.0f ? -1.0f : v > 1.0f ? 1.0f : v @@ -1998,9 +2012,10 @@ return 0; } -// -! TEST#0029 +#endif // NO_XSOUNDLIB + void CCtrlSamples::OnReverse() //---------------------------- { Modified: trunk/OpenMPT/mptrack/Ctrl_smp.h =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.h 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/mptrack/Ctrl_smp.h 2008-09-07 22:13:53 UTC (rev 223) @@ -1,7 +1,10 @@ #ifndef _CONTROL_SAMPLES_H_ #define _CONTROL_SAMPLES_H_ +// If defined, disables pitch shifting - time stretching. +#define NO_XSOUNDLIB + //======================================= class CCtrlSamples: public CModControlDlg //======================================= @@ -21,23 +24,21 @@ double m_dTimeStretchRatio; //rewbs.timeStretchMods -// -> CODE#0029 -// -> DESC="pitch shifting - time stretching" +#ifndef NO_XSOUNDLIB CComboBox m_ComboPitch, m_ComboQuality, m_ComboFFT; PVOID pSampleUndoBuffer; UINT UndoBufferSize; int PitchShift(float pitch); int TimeStretch(double ratio); -// -! TEST#0029 +#endif public: CCtrlSamples(); -// -> CODE#0029 -// -> DESC="pitch shifting - time stretching" +#ifndef NO_XSOUNDLIB ~CCtrlSamples(); -// -! TEST#0029 +#endif public: BOOL SetCurrentSample(UINT n, LONG lZoom=-1, BOOL bUpdNum=TRUE); @@ -94,14 +95,14 @@ afx_msg void OnVibRateChanged(); afx_msg void OnVScroll(UINT, UINT, CScrollBar *); afx_msg LRESULT OnCustomKeyMsg(WPARAM, LPARAM); //rewbs.customKeys -// -> CODE#0029 -// -> DESC="" + +#ifndef NO_XSOUNDLIB afx_msg void OnPitchShiftTimeStretch(); afx_msg void OnEnableStretchToSize(); afx_msg void OnEstimateSampleSize(); afx_msg void OnPitchShiftTimeStretchAccept(); afx_msg void OnPitchShiftTimeStretchCancel(); -// -! TEST#0029 +#endif //}}AFX_MSG DECLARE_MESSAGE_MAP() Modified: trunk/OpenMPT/mptrack/MPTRACK.sln =================================================================== --- trunk/OpenMPT/mptrack/MPTRACK.sln 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/mptrack/MPTRACK.sln 2008-09-07 22:13:53 UTC (rev 223) @@ -2,7 +2,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mptrack", "mptrack.vcproj", "{DB18719C-9177-4632-A9E0-7E72E2E6B05E}" ProjectSection(ProjectDependencies) = postProject {1FF4AB04-B22F-4CB8-AA2A-0C5095B5FEE4} = {1FF4AB04-B22F-4CB8-AA2A-0C5095B5FEE4} - {DCC2BB2F-6778-4FD3-9C00-D6CD8DC917B8} = {DCC2BB2F-6778-4FD3-9C00-D6CD8DC917B8} {71531076-78C7-488D-8FD6-9D841F20AADE} = {71531076-78C7-488D-8FD6-9D841F20AADE} {3C7281B0-D0E2-48ED-AE4D-A181FC77D8F7} = {3C7281B0-D0E2-48ED-AE4D-A181FC77D8F7} EndProjectSection Deleted: trunk/OpenMPT/mptrack/bin/getVersionFromCode.pl =================================================================== --- trunk/OpenMPT/mptrack/bin/getVersionFromCode.pl 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/mptrack/bin/getVersionFromCode.pl 2008-09-07 22:13:53 UTC (rev 223) @@ -1,9 +0,0 @@ -open(I, "mptrack.rc"); - -while(<I>) { - if (/\VALUE "FileVersion", "([0-9]*), ([0-9]*), ([0-9]*), ([0-9]*)".*/) { - printf("%d.%02d.%02d.%02d", $1, $2, $3, $4); - } -} - -close(I); \ No newline at end of file Deleted: trunk/OpenMPT/mptrack/bin/version =================================================================== --- trunk/OpenMPT/mptrack/bin/version 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/mptrack/bin/version 2008-09-07 22:13:53 UTC (rev 223) @@ -1 +0,0 @@ -1.17.02.48 \ No newline at end of file Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/mptrack/mptrack.rc 2008-09-07 22:13:53 UTC (rev 223) @@ -755,29 +755,35 @@ UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,353,83, 11,11 LTEXT "Auto-Vibrato",IDC_STATIC,275,50,41,8 - GROUPBOX "Pitch shifting / Time stretching",IDC_STATIC,370,22,150, - 78 - LTEXT "Pitch",IDC_STATIC,374,38,23,10 - LTEXT "Quality",IDC_STATIC,374,54,23,10 - LTEXT "FFT",IDC_STATIC,374,70,23,10 + GROUPBOX "Pitch shifting / Time stretching", + IDC_GROUPBOX_PITCH_TIME,370,22,150,78,NOT WS_VISIBLE + LTEXT "Pitch",IDC_TEXT_PITCH,374,38,23,10,NOT WS_VISIBLE + LTEXT "Quality",IDC_TEXT_QUALITY,374,54,23,10,NOT WS_VISIBLE + LTEXT "FFT",IDC_TEXT_FFT,374,70,23,10,NOT WS_VISIBLE CONTROL "Preview mode",IDC_CHECK2,"Button",BS_AUTOCHECKBOX | - BS_LEFTTEXT | BS_FLAT | WS_TABSTOP,373,83,65,11 + BS_LEFTTEXT | BS_FLAT | NOT WS_VISIBLE | WS_TABSTOP,373, + 83,65,11 CONTROL "Time stretching",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | - BS_LEFTTEXT | BS_FLAT | WS_TABSTOP,446,36,68,11 - EDITTEXT IDC_EDIT6,446,51,45,13,ES_RIGHT | ES_AUTOHSCROLL, - WS_EX_RIGHT - CTEXT "Static",IDC_STATIC1,448,69,67,10 - PUSHBUTTON "Process",IDC_BUTTON1,448,80,67,16,0,WS_EX_CLIENTEDGE - PUSHBUTTON "...",IDC_BUTTON2,502,51,13,13,0,WS_EX_CLIENTEDGE - PUSHBUTTON "Keep",IDC_BUTTON3,448,82,32,13,0,WS_EX_CLIENTEDGE - PUSHBUTTON "Restore",IDC_BUTTON4,482,82,33,13,0,WS_EX_CLIENTEDGE - COMBOBOX IDC_COMBO4,400,35,39,61,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_GROUP | WS_TABSTOP - COMBOBOX IDC_COMBO5,400,51,39,86,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_GROUP | WS_TABSTOP - COMBOBOX IDC_COMBO6,400,67,39,61,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_GROUP | WS_TABSTOP - LTEXT "%",IDC_STATIC,494,53,8,10 + BS_LEFTTEXT | BS_FLAT | NOT WS_VISIBLE | WS_TABSTOP,446, + 36,68,11 + EDITTEXT IDC_EDIT6,446,51,45,13,ES_RIGHT | ES_AUTOHSCROLL | NOT + WS_VISIBLE,WS_EX_RIGHT + CTEXT "Static",IDC_TEXT_PREVIEW,448,69,67,10,NOT WS_VISIBLE + PUSHBUTTON "Process",IDC_BUTTON1,448,80,67,16,NOT WS_VISIBLE, + WS_EX_CLIENTEDGE + PUSHBUTTON "...",IDC_BUTTON2,502,51,13,13,NOT WS_VISIBLE, + WS_EX_CLIENTEDGE + PUSHBUTTON "Keep",IDC_BUTTON3,448,82,32,13,NOT WS_VISIBLE, + WS_EX_CLIENTEDGE + PUSHBUTTON "Restore",IDC_BUTTON4,482,82,33,13,NOT WS_VISIBLE, + WS_EX_CLIENTEDGE + COMBOBOX IDC_COMBO4,400,35,39,61,CBS_DROPDOWNLIST | NOT + WS_VISIBLE | WS_VSCROLL | WS_GROUP | WS_TABSTOP + COMBOBOX IDC_COMBO5,400,51,39,86,CBS_DROPDOWNLIST | NOT + WS_VISIBLE | WS_VSCROLL | WS_GROUP | WS_TABSTOP + COMBOBOX IDC_COMBO6,400,67,39,61,CBS_DROPDOWNLIST | NOT + WS_VISIBLE | WS_VSCROLL | WS_GROUP | WS_TABSTOP + LTEXT "%",IDC_TEXT_PERCENT,494,53,8,10,NOT WS_VISIBLE END IDD_CONTROL_INSTRUMENTS DIALOGEX 0, 0, 558, 173 @@ -852,9 +858,9 @@ CONTROL "",IDC_SPIN11,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,351,153, 8,11 - COMBOBOX IDC_PLUGIN_VELOCITYSTYLE,371,115,82,50,CBS_DROPDOWNLIST | + COMBOBOX IDC_PLUGIN_VELOCITYSTYLE,367,115,83,50,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_PLUGIN_VOLUMESTYLE,373,148,77,53,CBS_DROPDOWNLIST | + COMBOBOX IDC_PLUGIN_VOLUMESTYLE,367,148,83,53,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBOTUNING,367,39,86,48,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP @@ -915,10 +921,10 @@ RTEXT "--",IDC_TEXT1,204,62,27,8 GROUPBOX "Pitch/Tempo Lock",IDC_STATIC,364,57,89,25 GROUPBOX "Sample Map",IDC_STATIC,461,27,62,141 - CTEXT "Note Velocity",IDC_STATIC,374,101,77,10,SS_CENTERIMAGE, - WS_EX_STATICEDGE - CTEXT "Volume command effect",IDC_STATIC,374,133,77,10, + CTEXT "Velocity handling",IDC_STATIC,367,102,83,10, SS_CENTERIMAGE,WS_EX_STATICEDGE + CTEXT "Volume handling",IDC_STATIC,367,133,83,10, + SS_CENTERIMAGE,WS_EX_STATICEDGE GROUPBOX "Tuning (experimental)",IDC_STATIC,364,28,92,28 END Modified: trunk/OpenMPT/mptrack/mptrack.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack.vcproj 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/mptrack/mptrack.vcproj 2008-09-07 22:13:53 UTC (rev 223) @@ -48,12 +48,12 @@ <Tool Name="VCLinkerTool" AdditionalOptions="/MACHINE:I386" - AdditionalDependencies="winmm.lib strmiids.lib dmoguids.lib xsoundlib.lib version.lib opengl32.lib glu32.lib Rpcrt4.lib" + AdditionalDependencies="winmm.lib strmiids.lib dmoguids.lib version.lib opengl32.lib glu32.lib Rpcrt4.lib" OutputFile=".\Debug/mptrack.exe" Version="5.0" LinkIncremental="2" SuppressStartupBanner="TRUE" - AdditionalLibraryDirectories="..\xsoundlib\Debug" + AdditionalLibraryDirectories="" DelayLoadDLLs="" GenerateDebugInformation="TRUE" AssemblyDebug="1" @@ -125,12 +125,12 @@ <Tool Name="VCLinkerTool" AdditionalOptions="/MACHINE:I386" - AdditionalDependencies="winmm.lib strmiids.lib dmoguids.lib xsoundlib.lib version.lib opengl32.lib glu32.lib Rpcrt4.lib" + AdditionalDependencies="winmm.lib strmiids.lib dmoguids.lib version.lib opengl32.lib glu32.lib Rpcrt4.lib" OutputFile=".\Bin/mptrack.exe" Version="5.0" LinkIncremental="1" SuppressStartupBanner="TRUE" - AdditionalLibraryDirectories="..\xsoundlib\Release" + AdditionalLibraryDirectories="" GenerateMapFile="FALSE" MapFileName=".\Release/mptrack.map" SubSystem="2"/> Modified: trunk/OpenMPT/mptrack/resource.h =================================================================== --- trunk/OpenMPT/mptrack/resource.h 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/mptrack/resource.h 2008-09-07 22:13:53 UTC (rev 223) @@ -701,6 +701,7 @@ #define IDC_CHORDDETECTWAITTIME 2206 #define IDC_STATIC2 2207 #define IDC_STATIC1 2208 +#define IDC_TEXT_PREVIEW 2208 #define IDC_MACROPLUG 2209 #define IDC_MACROPARAM 2210 #define IDC_SAMPLE_LENGTH_NEW 2211 @@ -812,6 +813,11 @@ #define IDC_SPINMOVEMAPPING 2325 #define IDC_BUTTON_HALF 2326 #define IDC_BUTTON_DOUBLE 2327 +#define IDC_GROUPBOX_PITCH_TIME 2328 +#define IDC_TEXT_PITCH 2329 +#define IDC_TEXT_QUALITY 2330 +#define IDC_TEXT_FFT 2331 +#define IDC_TEXT_PERCENT 2332 #define ID_FILE_NEWMOD 32771 #define ID_FILE_NEWXM 32772 #define ID_FILE_NEWS3M 32773 @@ -1043,7 +1049,7 @@ #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 516 #define _APS_NEXT_COMMAND_VALUE 59212 -#define _APS_NEXT_CONTROL_VALUE 2328 +#define _APS_NEXT_CONTROL_VALUE 2333 #define _APS_NEXT_SYMED_VALUE 901 #endif #endif Modified: trunk/OpenMPT/soundlib/Dlsbank.cpp =================================================================== --- trunk/OpenMPT/soundlib/Dlsbank.cpp 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/soundlib/Dlsbank.cpp 2008-09-07 22:13:53 UTC (rev 223) @@ -1,10 +1,10 @@ /* - * This program is free software; you can redistribute it and modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the license or (at your - * option) any later version. + * OpenMPT * + * Dlsbank.cpp + * * Authors: Olivier Lapicque <oli...@jp...> + * OpenMPT devs */ /////////////////////////////////////////////////////////////////////////// Modified: trunk/OpenMPT/soundlib/Fastmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Fastmix.cpp 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/soundlib/Fastmix.cpp 2008-09-07 22:13:53 UTC (rev 223) @@ -1,10 +1,10 @@ /* - * This program is free software; you can redistribute it and modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the license or (at your - * option) any later version. + * OpenMPT * + * Fastmix.cpp + * * Authors: Olivier Lapicque <oli...@jp...> + * OpenMPT devs */ #include "stdafx.h" Modified: trunk/OpenMPT/soundlib/LOAD_AMF.CPP =================================================================== --- trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2008-09-07 22:13:53 UTC (rev 223) @@ -165,7 +165,7 @@ -BOOL CSoundFile::ReadAMF(LPCBYTE lpStream, DWORD dwMemLength) +BOOL CSoundFile::ReadAMF(LPCBYTE lpStream, const DWORD dwMemLength) //----------------------------------------------------------- { const AMFFILEHEADER *pfh = (AMFFILEHEADER *)lpStream; @@ -251,7 +251,8 @@ MODINSTRUMENT *psmp = &Ins[iData+1]; if (psmp->nLength) { - dwMemPos += ReadSample(psmp, RS_PCM8S, (LPCSTR)(lpStream+dwMemPos), dwMemLength); + if(dwMemPos > dwMemLength) return FALSE; + dwMemPos += ReadSample(psmp, RS_PCM8S, (LPCSTR)(lpStream+dwMemPos), dwMemLength - dwMemPos); } } return TRUE; Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2008-09-07 22:13:53 UTC (rev 223) @@ -1,10 +1,10 @@ /* - * This program is free software; you can redistribute it and modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the license or (at your - * option) any later version. + * OpenMPT * + * Load_it.cpp + * * Authors: Olivier Lapicque <oli...@jp...> + * OpenMPT devs */ #include "stdafx.h" @@ -473,8 +473,13 @@ DWORD streamPos = 0; DWORD version; - if(dwMemLength < 12) return FALSE; + // Macro used to make sure that given amount of bytes can be read. + // Returns FALSE from this function if reading is not possible. + #define ASSERT_CAN_READ(x) \ + if( streamPos > dwMemLength || x > dwMemLength - streamPos ) return FALSE; + ASSERT_CAN_READ(12); + // Check file ID memcpy(&id,lpStream+streamPos,sizeof(DWORD)); @@ -494,7 +499,8 @@ streamPos += sizeof(DWORD); // name string - if (streamPos+len<=dwMemLength && len<=sizeof(m_szNames[0])) { + ASSERT_CAN_READ(len); + if (len<=sizeof(m_szNames[0])) { memcpy(m_szNames[0],lpStream+streamPos,len); streamPos += len; m_szNames[0][sizeof(m_szNames[0])-1] = '\0'; @@ -504,7 +510,7 @@ // Song comments // comment string length - if(streamPos + 4 > dwMemLength) return FALSE; + ASSERT_CAN_READ(4); memcpy(&id,lpStream+streamPos,sizeof(DWORD)); streamPos += sizeof(DWORD); if(id > uint16_max) return FALSE; @@ -519,13 +525,15 @@ m_lpszSongComments = NULL; // m_lpszSongComments - if (m_lpszSongComments && id && streamPos + id <= dwMemLength) { + if (m_lpszSongComments && id) + { + ASSERT_CAN_READ(id); memcpy(&m_lpszSongComments[0],lpStream+streamPos,id); streamPos += id; } // Song global config - if(streamPos + 5*4 > dwMemLength) return FALSE; + ASSERT_CAN_READ(5*4); // m_dwSongFlags memcpy(&id,lpStream+streamPos,sizeof(DWORD)); @@ -555,7 +563,7 @@ streamPos += sizeof(DWORD); // Song channels data - if(streamPos + 2*4 > dwMemLength) return FALSE; + ASSERT_CAN_READ(2*4); // m_nChannels memcpy(&id,lpStream+streamPos,sizeof(DWORD)); @@ -571,9 +579,8 @@ // Channels' data for(i=0; i<m_nChannels; i++){ + ASSERT_CAN_READ(3*4 + len); - if(streamPos + 3*4 + len > dwMemLength) return FALSE; - // ChnSettings[i].nPan memcpy(&id,lpStream+streamPos,sizeof(DWORD)); ChnSettings[i].nPan = id; @@ -596,23 +603,24 @@ // Song mix plugins // size of mix plugins data - if(streamPos + 4 > dwMemLength) return FALSE; + ASSERT_CAN_READ(4); memcpy(&id,lpStream+streamPos,sizeof(DWORD)); streamPos += sizeof(DWORD); // mix plugins - if(id > dwMemLength - streamPos) return FALSE; + ASSERT_CAN_READ(id); streamPos += LoadMixPlugins(lpStream+streamPos, id); // Song midi config // midi cfg data length - if(streamPos + 4 > dwMemLength) return FALSE; + ASSERT_CAN_READ(4); memcpy(&id,lpStream+streamPos,sizeof(DWORD)); streamPos += sizeof(DWORD); // midi cfg - if (id<=sizeof(m_MidiCfg) && id+streamPos<=dwMemLength) { + ASSERT_CAN_READ(id); + if (id<=sizeof(m_MidiCfg)) { memcpy(&m_MidiCfg,lpStream+streamPos,id); streamPos += id; } @@ -620,14 +628,14 @@ // Song Instruments // m_nInstruments - if(streamPos + 4 > dwMemLength) return FALSE; + ASSERT_CAN_READ(4); memcpy(&id,lpStream+streamPos,sizeof(DWORD)); m_nInstruments = id; - if(m_nInstruments > 256) return FALSE; + if(m_nInstruments > MAX_INSTRUMENTS) return FALSE; streamPos += sizeof(DWORD); // path string length (=_MAX_PATH) - if(streamPos + 4 > dwMemLength) return FALSE; + ASSERT_CAN_READ(4); memcpy(&id,lpStream+streamPos,sizeof(DWORD)); len = id; if(len > _MAX_PATH) return FALSE; @@ -635,35 +643,30 @@ // instruments' paths for(i=0; i<m_nInstruments; i++){ - if (len+streamPos<=dwMemLength) - { - memcpy(&m_szInstrumentPath[i][0],lpStream+streamPos,len); - streamPos += len; - } - else return FALSE; + ASSERT_CAN_READ(len); + memcpy(&m_szInstrumentPath[i][0],lpStream+streamPos,len); + streamPos += len; } // Song Orders // size of order array (=MAX_ORDERS) - if(streamPos + 4 > dwMemLength) return FALSE; + ASSERT_CAN_READ(4); memcpy(&id,lpStream+streamPos,sizeof(DWORD)); size = id; if(size > MAX_ORDERS) return FALSE; streamPos += sizeof(DWORD); // order data - if (size+streamPos<=dwMemLength) - { - Order.ReadAsByte(lpStream+streamPos, size, dwMemLength-streamPos); - streamPos += size; - } - else return FALSE; + ASSERT_CAN_READ(size); + Order.ReadAsByte(lpStream+streamPos, size, dwMemLength-streamPos); + streamPos += size; + // Song Patterns - if(streamPos + 12 > dwMemLength) return FALSE; + ASSERT_CAN_READ(3*4); // number of patterns (=MAX_PATTERNS) memcpy(&id,lpStream+streamPos,sizeof(DWORD)); size = id; @@ -684,6 +687,7 @@ if (len<=MAX_PATTERNNAME && m_nPatternNames<=MAX_PATTERNS) { m_lpszPatternNames = new char[m_nPatternNames * len]; + ASSERT_CAN_READ(m_nPatternNames * len); memcpy(&m_lpszPatternNames[0],lpStream+streamPos,m_nPatternNames * len); } else return FALSE; @@ -691,9 +695,10 @@ streamPos += m_nPatternNames * len; // modcommand data length - if(streamPos + 4 > dwMemLength) return FALSE; + ASSERT_CAN_READ(4); memcpy(&id,lpStream+streamPos,sizeof(DWORD)); n = id; + if(n != 6) return FALSE; streamPos += sizeof(DWORD); for(UINT npat=0; npat<size; npat++){ @@ -702,9 +707,9 @@ if(Patterns[npat]) { FreePattern(Patterns[npat]); Patterns[npat] = NULL; } // PatternSize[npat] - if(streamPos + 4 > dwMemLength) return FALSE; + ASSERT_CAN_READ(4); memcpy(&id,lpStream+streamPos,sizeof(DWORD)); - if(id > 1024) return FALSE; + if(id > MAX_PATTERN_ROWS) return FALSE; Patterns[npat].Resize(id); streamPos += sizeof(DWORD); @@ -736,14 +741,14 @@ ITSAMPLESTRUCT pis; // Read original number of samples - if(streamPos + 4 > dwMemLength) return FALSE; + ASSERT_CAN_READ(4); memcpy(&id,lpStream+streamPos,sizeof(DWORD)); if(id > MAX_SAMPLES) return FALSE; m_nSamples = id; streamPos += sizeof(DWORD); // Read number of embeded samples - if(streamPos + 4 > dwMemLength) return FALSE; + ASSERT_CAN_READ(4); memcpy(&id,lpStream+streamPos,sizeof(DWORD)); if(id > MAX_SAMPLES) return FALSE; n = id; @@ -752,7 +757,7 @@ // Read samples for(i=0; i<n; i++){ - if(streamPos + 4 + sizeof(ITSAMPLESTRUCT) + 4 > dwMemLength) return FALSE; + ASSERT_CAN_READ(4 + sizeof(ITSAMPLESTRUCT) + 4); // Sample id number memcpy(&id,lpStream+streamPos,sizeof(DWORD)); @@ -841,7 +846,7 @@ __int16 fsize = 0; BYTE * ptr = (BYTE *)(lpStream + streamPos); - if (streamPos + 4 <= dwMemLength) { + if (streamPos <= dwMemLength - 4) { fcode = (*((__int32 *)ptr)); } @@ -903,6 +908,8 @@ } return TRUE; + + #undef ASSERT_CAN_READ } // -! NEW_FEATURE#0023 Modified: trunk/OpenMPT/soundlib/Load_mid.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mid.cpp 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/soundlib/Load_mid.cpp 2008-09-07 22:13:53 UTC (rev 223) @@ -1,10 +1,10 @@ /* - * This program is free software; you can redistribute it and modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the license or (at your - * option) any later version. + * OpenMPT * + * Load_mid.cpp + * * Authors: Olivier Lapicque <oli...@jp...> + * OpenMPT devs */ ////////////////////////////////////////////// Modified: trunk/OpenMPT/soundlib/Load_xm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_xm.cpp 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/soundlib/Load_xm.cpp 2008-09-07 22:13:53 UTC (rev 223) @@ -404,6 +404,8 @@ penv->nPan = 128; penv->nPPC = 5*12; SetDefaultInstrumentValues(penv); + penv->nPluginVelocityHandling = PLUGIN_VELOCITYHANDLING_CHANNEL; + penv->nPluginVolumeHandling = PLUGIN_VOLUMEHANDLING_IGNORE; if (xmsh.vtype & 1) penv->dwFlags |= ENV_VOLUME; if (xmsh.vtype & 2) penv->dwFlags |= ENV_VOLSUSTAIN; if (xmsh.vtype & 4) penv->dwFlags |= ENV_VOLLOOP; Modified: trunk/OpenMPT/soundlib/Mmcmp.cpp =================================================================== --- trunk/OpenMPT/soundlib/Mmcmp.cpp 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/soundlib/Mmcmp.cpp 2008-09-07 22:13:53 UTC (rev 223) @@ -1,9 +1,8 @@ /* - * This program is free software; you can redistribute it and modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the license or (at your - * option) any later version. + * OpenMPT * + * Mmcmp.cpp + * * Authors: Olivier Lapicque <oli...@jp...> */ Modified: trunk/OpenMPT/soundlib/Mmx_mix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Mmx_mix.cpp 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/soundlib/Mmx_mix.cpp 2008-09-07 22:13:53 UTC (rev 223) @@ -1,10 +1,11 @@ /* - * This program is free software; you can redistribute it and modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the license or (at your - * option) any later version. + * OpenMPT * + * Mmx_mix.cpp + * * Authors: Olivier Lapicque <oli...@jp...> + * OpenMPT devs + * * Name Date Description * Olivier Lapicque --/--/-- Creation * Trevor Nunes 26/01/04 encapsulated MMX,AMD,SSE with #define flags Modified: trunk/OpenMPT/soundlib/Sampleio.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sampleio.cpp 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/soundlib/Sampleio.cpp 2008-09-07 22:13:53 UTC (rev 223) @@ -1,10 +1,10 @@ /* - * This program is free software; you can redistribute it and modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the license or (at your - * option) any later version. + * OpenMPT * + * Sampleio.cpp + * * Authors: Olivier Lapicque <oli...@jp...> + * OpenMPT devs */ #include "stdafx.h" Modified: trunk/OpenMPT/soundlib/Snd_dsp.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_dsp.cpp 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/soundlib/Snd_dsp.cpp 2008-09-07 22:13:53 UTC (rev 223) @@ -1,10 +1,10 @@ /* - * This program is free software; you can redistribute it and modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the license or (at your - * option) any later version. + * OpenMPT * + * Snd_dsp.cpp + * * Authors: Olivier Lapicque <oli...@jp...> + * OpenMPT devs */ #include "stdafx.h" Modified: trunk/OpenMPT/soundlib/Snd_eq.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_eq.cpp 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/soundlib/Snd_eq.cpp 2008-09-07 22:13:53 UTC (rev 223) @@ -1,10 +1,10 @@ /* - * This program is free software; you can redistribute it and modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the license or (at your - * option) any later version. + * OpenMPT * + * Snd_eq.cpp + * * Authors: Olivier Lapicque <oli...@jp...> + * OpenMPT devs * * Name Date Description * Modified: trunk/OpenMPT/soundlib/Snd_flt.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_flt.cpp 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/soundlib/Snd_flt.cpp 2008-09-07 22:13:53 UTC (rev 223) @@ -1,10 +1,10 @@ /* - * This program is free software; you can redistribute it and modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the license or (at your - * option) any later version. + * OpenMPT * + * Snd_flt.cpp + * * Authors: Olivier Lapicque <oli...@jp...> + * OpenMPT devs */ #include "stdafx.h" Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2008-09-07 22:13:53 UTC (rev 223) @@ -1,10 +1,10 @@ /* - * This program is free software; you can redistribute it and modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the license or (at your - * option) any later version. + * OpenMPT * + * Snd_fx.cpp + * * Authors: Olivier Lapicque <oli...@jp...> + * OpenMPT devs */ #include "stdafx.h" Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2008-09-07 22:13:53 UTC (rev 223) @@ -1,10 +1,10 @@ /* - * This program is free software; you can redistribute it and modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the license or (at your - * option) any later version. + * OpenMPT * + * Sndfile.cpp + * * Authors: Olivier Lapicque <oli...@jp...> + * OpenMPT devs */ #include "stdafx.h" @@ -19,6 +19,8 @@ #include <vector> #include <algorithm> +#define str_SampleAllocationError (GetStrI18N(_TEXT("Sample allocation error"))) +#define str_Error (GetStrI18N(_TEXT("Error"))) #ifndef NO_COPYRIGHT #ifndef NO_MMCMP_SUPPORT @@ -1891,10 +1893,12 @@ UINT CSoundFile::ReadSample(MODINSTRUMENT *pIns, UINT nFlags, LPCSTR lpMemFile, DWORD dwMemLength, const WORD format) //----------------------------------------------------------------------------------------------------------------------- { + if(pIns->nLength > MAX_SAMPLE_LENGTH) + pIns->nLength = MAX_SAMPLE_LENGTH; + UINT len = 0, mem = pIns->nLength+6; if ((!pIns) || (pIns->nLength < 4) || (!lpMemFile)) return 0; - if (pIns->nLength > MAX_SAMPLE_LENGTH) pIns->nLength = MAX_SAMPLE_LENGTH; pIns->uFlags &= ~(CHN_16BIT|CHN_STEREO); if (nFlags & RSF_16BIT) { @@ -1906,11 +1910,24 @@ mem *= 2; pIns->uFlags |= CHN_STEREO; } + if ((pIns->pSample = AllocateSample(mem)) == NULL) { pIns->nLength = 0; return 0; } + + // Check that allocated memory size is not less than what the modinstrument itself + // thinks it is. + if( mem < pIns->GetSampleSizeInBytes() ) + { + pIns->nLength = 0; + FreeSample(pIns->pSample); + pIns->pSample = NULL; + MessageBox(0, str_SampleAllocationError, str_Error, MB_ICONERROR); + return 0; + } + switch(nFlags) { // 1: 8-bit unsigned PCM data Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/soundlib/Sndfile.h 2008-09-07 22:13:53 UTC (rev 223) @@ -1,11 +1,12 @@ /* - * This program is free software; you can redistribute it and modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the license or (at your - * option) any later version. + * OpenMPT * + * Sndfile.h + * * Authors: Olivier Lapicque <oli...@jp...> + * OpenMPT devs */ + #include "../mptrack/SoundFilePlayConfig.h" #include "tuning.h" #include "mod_specifications.h" @@ -30,7 +31,8 @@ #define MOD_AMIGAC2 0x1AB // -> CODE#0006 // -> DESC="misc quantity changes" -#define MAX_SAMPLE_LENGTH 0x10000000 // 0x04000000 (64MB -> now 256MB) +#define MAX_SAMPLE_LENGTH 0x10000000 // 0x04000000 (64MB -> now 256MB). + // Note: Sample size in bytes can be more than 256 MB. // -! BEHAVIOUR_CHANGE#0006 #define MAX_SAMPLE_RATE 100000 #define MAX_ORDERS 256 @@ -45,7 +47,8 @@ //#else // -> CODE#0006 // -> DESC="misc quantity changes" -#define MAX_CHANNELS 256 //200 //Note: MAX_BASECHANNELS defines max pattern channels +#define MAX_CHANNELS 256 //200 //Note: This is the maximum number of sound channels, + // see MAX_BASECHANNELS for max pattern channels. // -! BEHAVIOUR_CHANGE#0006 //#endif // -> CODE#0006 @@ -1050,7 +1053,7 @@ BOOL ReadDMF(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadPTM(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadDBM(LPCBYTE lpStream, DWORD dwMemLength); - BOOL ReadAMF(LPCBYTE lpStream, DWORD dwMemLength); + BOOL ReadAMF(LPCBYTE lpStream, const DWORD dwMemLength); BOOL ReadMT2(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadPSM(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadJ2B(LPCBYTE lpStream, DWORD dwMemLength); Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2008-09-07 22:13:53 UTC (rev 223) @@ -1,10 +1,10 @@ /* - * This program is free software; you can redistribute it and modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the license or (at your - * option) any later version. + * OpenMPT * + * Sndmix.cpp + * * Authors: Olivier Lapicque <oli...@jp...> + * OpenMPT devs */ #include "stdafx.h" Modified: trunk/OpenMPT/soundlib/Tables.cpp =================================================================== --- trunk/OpenMPT/soundlib/Tables.cpp 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/soundlib/Tables.cpp 2008-09-07 22:13:53 UTC (rev 223) @@ -1,10 +1,10 @@ /* - * This program is free software; you can redistribute it and modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the license or (at your - * option) any later version. + * OpenMPT * + * Tables.cpp + * * Authors: Olivier Lapicque <oli...@jp...> + * OpenMPT devs * * Name Date Description: * Olivier Lapicque --/--/-- Creator Modified: trunk/OpenMPT/soundlib/Waveform.cpp =================================================================== --- trunk/OpenMPT/soundlib/Waveform.cpp 2008-08-24 20:33:31 UTC (rev 222) +++ trunk/OpenMPT/soundlib/Waveform.cpp 2008-09-07 22:13:53 UTC (rev 223) @@ -1,10 +1,10 @@ /* - * This program is free software; you can redistribute it and modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the license or (at your - * option) any later version. + * OpenMPT * + * Waveform.cpp + * * Authors: Olivier Lapicque <oli...@jp...> + * OpenMPT devs */ #include "stdafx.h" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2008-10-13 14:26:27
|
Revision: 227 http://modplug.svn.sourceforge.net/modplug/?rev=227&view=rev Author: relabsoluness Date: 2008-10-13 14:25:58 +0000 (Mon, 13 Oct 2008) Log Message: ----------- + Added SoundTouch library to SVN(LGPL); to be used for time stretching. Added Paths: ----------- trunk/OpenMPT/soundtouch/ trunk/OpenMPT/soundtouch/3dnow_win.cpp trunk/OpenMPT/soundtouch/AAFilter.cpp trunk/OpenMPT/soundtouch/AAFilter.h trunk/OpenMPT/soundtouch/BPMDetect.h trunk/OpenMPT/soundtouch/COPYING.TXT trunk/OpenMPT/soundtouch/FIFOSampleBuffer.cpp trunk/OpenMPT/soundtouch/FIFOSampleBuffer.h trunk/OpenMPT/soundtouch/FIFOSamplePipe.h trunk/OpenMPT/soundtouch/FIRFilter.cpp trunk/OpenMPT/soundtouch/FIRFilter.h trunk/OpenMPT/soundtouch/README.html trunk/OpenMPT/soundtouch/RateTransposer.cpp trunk/OpenMPT/soundtouch/RateTransposer.h trunk/OpenMPT/soundtouch/STTypes.h trunk/OpenMPT/soundtouch/SoundTouch.cpp trunk/OpenMPT/soundtouch/SoundTouch.h trunk/OpenMPT/soundtouch/TDStretch.cpp trunk/OpenMPT/soundtouch/TDStretch.h trunk/OpenMPT/soundtouch/cpu_detect.h trunk/OpenMPT/soundtouch/cpu_detect_x86_win.cpp trunk/OpenMPT/soundtouch/mmx_optimized.cpp trunk/OpenMPT/soundtouch/soundtouch-1.3.1.zip trunk/OpenMPT/soundtouch/soundtouch.vcproj trunk/OpenMPT/soundtouch/sse_optimized.cpp Added: trunk/OpenMPT/soundtouch/3dnow_win.cpp =================================================================== --- trunk/OpenMPT/soundtouch/3dnow_win.cpp (rev 0) +++ trunk/OpenMPT/soundtouch/3dnow_win.cpp 2008-10-13 14:25:58 UTC (rev 227) @@ -0,0 +1,350 @@ +//////////////////////////////////////////////////////////////////////////////// +/// +/// Win32 version of the AMD 3DNow! optimized routines for AMD K6-2/Athlon +/// processors. All 3DNow! optimized functions have been gathered into this +/// single source code file, regardless to their class or original source code +/// file, in order to ease porting the library to other compiler and processor +/// platforms. +/// +/// By the way; the performance gain depends heavily on the CPU generation: On +/// K6-2 these routines provided speed-up of even 2.4 times, while on Athlon the +/// difference to the original routines stayed at unremarkable 8%! Such a small +/// improvement on Athlon is due to 3DNow can perform only two operations in +/// parallel, and obviously also the Athlon FPU is doing a very good job with +/// the standard C floating point routines! Here these routines are anyway, +/// although it might not be worth the effort to convert these to GCC platform, +/// for Athlon CPU at least. The situation is different regarding the SSE +/// optimizations though, thanks to the four parallel operations of SSE that +/// already make a difference. +/// +/// This file is to be compiled in Windows platform with Microsoft Visual C++ +/// Compiler. Please see '3dnow_gcc.cpp' for the gcc compiler version for all +/// GNU platforms (if file supplied). +/// +/// NOTICE: If using Visual Studio 6.0, you'll need to install the "Visual C++ +/// 6.0 processor pack" update to support 3DNow! instruction set. The update is +/// available for download at Microsoft Developers Network, see here: +/// http://msdn.microsoft.com/vstudio/downloads/tools/ppack/default.aspx +/// +/// If the above URL is expired or removed, go to "http://msdn.microsoft.com" and +/// perform a search with keywords "processor pack". +/// +/// Author : Copyright (c) Olli Parviainen +/// Author e-mail : oparviai 'at' iki.fi +/// SoundTouch WWW: http://www.surina.net/soundtouch +/// +//////////////////////////////////////////////////////////////////////////////// +// +// Last changed : $Date: 2006/02/05 16:44:06 $ +// File revision : $Revision: 1.10 $ +// +// $Id: 3dnow_win.cpp,v 1.10 2006/02/05 16:44:06 Olli Exp $ +// +//////////////////////////////////////////////////////////////////////////////// +// +// License : +// +// SoundTouch audio processing library +// Copyright (c) Olli Parviainen +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//////////////////////////////////////////////////////////////////////////////// + +#include "cpu_detect.h" +#include "STTypes.h" + +#ifndef WIN32 +#error "wrong platform - this source code file is exclusively for Win32 platform" +#endif + +using namespace soundtouch; + +#ifdef ALLOW_3DNOW +// 3DNow! routines available only with float sample type + +////////////////////////////////////////////////////////////////////////////// +// +// implementation of 3DNow! optimized functions of class 'TDStretch3DNow' +// +////////////////////////////////////////////////////////////////////////////// + +#include "TDStretch.h" +#include <limits.h> + +// these are declared in 'TDStretch.cpp' +extern int scanOffsets[4][24]; + + +// Calculates cross correlation of two buffers +double TDStretch3DNow::calcCrossCorrStereo(const float *pV1, const float *pV2) const +{ + uint overlapLengthLocal = overlapLength; + float corr; + + // Calculates the cross-correlation value between 'pV1' and 'pV2' vectors + /* + c-pseudocode: + + corr = 0; + for (i = 0; i < overlapLength / 4; i ++) + { + corr += pV1[0] * pV2[0]; + pV1[1] * pV2[1]; + pV1[2] * pV2[2]; + pV1[3] * pV2[3]; + pV1[4] * pV2[4]; + pV1[5] * pV2[5]; + pV1[6] * pV2[6]; + pV1[7] * pV2[7]; + + pV1 += 8; + pV2 += 8; + } + */ + + _asm + { + // give prefetch hints to CPU of what data are to be needed soonish. + // give more aggressive hints on pV1 as that changes more between different calls + // while pV2 stays the same. + prefetch [pV1] + prefetch [pV2] + prefetch [pV1 + 32] + + mov eax, dword ptr pV2 + mov ebx, dword ptr pV1 + + pxor mm0, mm0 + + mov ecx, overlapLengthLocal + shr ecx, 2 // div by four + + loop1: + movq mm1, [eax] + prefetch [eax + 32] // give a prefetch hint to CPU what data are to be needed soonish + pfmul mm1, [ebx] + prefetch [ebx + 64] // give a prefetch hint to CPU what data are to be needed soonish + + movq mm2, [eax + 8] + pfadd mm0, mm1 + pfmul mm2, [ebx + 8] + + movq mm3, [eax + 16] + pfadd mm0, mm2 + pfmul mm3, [ebx + 16] + + movq mm4, [eax + 24] + pfadd mm0, mm3 + pfmul mm4, [ebx + 24] + + add eax, 32 + pfadd mm0, mm4 + add ebx, 32 + + dec ecx + jnz loop1 + + // add halfs of mm0 together and return the result. + // note: mm1 is used as a dummy parameter only, we actually don't care about it's value + pfacc mm0, mm1 + movd corr, mm0 + femms + } + + return corr; +} + + + + +////////////////////////////////////////////////////////////////////////////// +// +// implementation of 3DNow! optimized functions of class 'FIRFilter' +// +////////////////////////////////////////////////////////////////////////////// + +#include "FIRFilter.h" + +FIRFilter3DNow::FIRFilter3DNow() : FIRFilter() +{ + filterCoeffsUnalign = NULL; +} + + +FIRFilter3DNow::~FIRFilter3DNow() +{ + delete[] filterCoeffsUnalign; +} + + +// (overloaded) Calculates filter coefficients for 3DNow! routine +void FIRFilter3DNow::setCoefficients(const float *coeffs, uint newLength, uint uResultDivFactor) +{ + uint i; + float fDivider; + + FIRFilter::setCoefficients(coeffs, newLength, uResultDivFactor); + + // Scale the filter coefficients so that it won't be necessary to scale the filtering result + // also rearrange coefficients suitably for 3DNow! + // Ensure that filter coeffs array is aligned to 16-byte boundary + delete[] filterCoeffsUnalign; + filterCoeffsUnalign = new float[2 * newLength + 4]; + filterCoeffsAlign = (float *)(((uint)filterCoeffsUnalign + 15) & -16); + + fDivider = (float)resultDivider; + + // rearrange the filter coefficients for mmx routines + for (i = 0; i < newLength; i ++) + { + filterCoeffsAlign[2 * i + 0] = + filterCoeffsAlign[2 * i + 1] = coeffs[i + 0] / fDivider; + } +} + + +// 3DNow!-optimized version of the filter routine for stereo sound +uint FIRFilter3DNow::evaluateFilterStereo(float *dest, const float *src, const uint numSamples) const +{ + float *filterCoeffsLocal = filterCoeffsAlign; + uint count = (numSamples - length) & -2; + uint lengthLocal = length / 4; + + assert(length != 0); + assert(count % 2 == 0); + + /* original code: + + double suml1, suml2; + double sumr1, sumr2; + uint i, j; + + for (j = 0; j < count; j += 2) + { + const float *ptr; + + suml1 = sumr1 = 0.0; + suml2 = sumr2 = 0.0; + ptr = src; + filterCoeffsLocal = filterCoeffs; + for (i = 0; i < lengthLocal; i ++) + { + // unroll loop for efficiency. + + suml1 += ptr[0] * filterCoeffsLocal[0] + + ptr[2] * filterCoeffsLocal[2] + + ptr[4] * filterCoeffsLocal[4] + + ptr[6] * filterCoeffsLocal[6]; + + sumr1 += ptr[1] * filterCoeffsLocal[1] + + ptr[3] * filterCoeffsLocal[3] + + ptr[5] * filterCoeffsLocal[5] + + ptr[7] * filterCoeffsLocal[7]; + + suml2 += ptr[8] * filterCoeffsLocal[0] + + ptr[10] * filterCoeffsLocal[2] + + ptr[12] * filterCoeffsLocal[4] + + ptr[14] * filterCoeffsLocal[6]; + + sumr2 += ptr[9] * filterCoeffsLocal[1] + + ptr[11] * filterCoeffsLocal[3] + + ptr[13] * filterCoeffsLocal[5] + + ptr[15] * filterCoeffsLocal[7]; + + ptr += 16; + filterCoeffsLocal += 8; + } + dest[0] = (float)suml1; + dest[1] = (float)sumr1; + dest[2] = (float)suml2; + dest[3] = (float)sumr2; + + src += 4; + dest += 4; + } + + */ + _asm + { + mov eax, dword ptr dest + mov ebx, dword ptr src + mov edx, count + shr edx, 1 + + loop1: + // "outer loop" : during each round 2*2 output samples are calculated + prefetch [ebx] // give a prefetch hint to CPU what data are to be needed soonish + prefetch [filterCoeffsLocal] // give a prefetch hint to CPU what data are to be needed soonish + + mov esi, ebx + mov edi, filterCoeffsLocal + pxor mm0, mm0 + pxor mm1, mm1 + mov ecx, lengthLocal + + loop2: + // "inner loop" : during each round four FIR filter taps are evaluated for 2*2 output samples + movq mm2, [edi] + movq mm3, mm2 + prefetch [edi + 32] // give a prefetch hint to CPU what data are to be needed soonish + pfmul mm2, [esi] + prefetch [esi + 32] // give a prefetch hint to CPU what data are to be needed soonish + pfmul mm3, [esi + 8] + + movq mm4, [edi + 8] + movq mm5, mm4 + pfadd mm0, mm2 + pfmul mm4, [esi + 8] + pfadd mm1, mm3 + pfmul mm5, [esi + 16] + + movq mm2, [edi + 16] + movq mm6, mm2 + pfadd mm0, mm4 + pfmul mm2, [esi + 16] + pfadd mm1, mm5 + pfmul mm6, [esi + 24] + + movq mm3, [edi + 24] + movq mm7, mm3 + pfadd mm0, mm2 + pfmul mm3, [esi + 24] + pfadd mm1, mm6 + pfmul mm7, [esi + 32] + add esi, 32 + pfadd mm0, mm3 + add edi, 32 + pfadd mm1, mm7 + + dec ecx + jnz loop2 + + movq [eax], mm0 + add ebx, 16 + movq [eax + 8], mm1 + add eax, 16 + + dec edx + jnz loop1 + + femms + } + + return count; +} + + +#endif // ALLOW_3DNOW Added: trunk/OpenMPT/soundtouch/AAFilter.cpp =================================================================== --- trunk/OpenMPT/soundtouch/AAFilter.cpp (rev 0) +++ trunk/OpenMPT/soundtouch/AAFilter.cpp 2008-10-13 14:25:58 UTC (rev 227) @@ -0,0 +1,184 @@ +//////////////////////////////////////////////////////////////////////////////// +/// +/// FIR low-pass (anti-alias) filter with filter coefficient design routine and +/// MMX optimization. +/// +/// Anti-alias filter is used to prevent folding of high frequencies when +/// transposing the sample rate with interpolation. +/// +/// Author : Copyright (c) Olli Parviainen +/// Author e-mail : oparviai 'at' iki.fi +/// SoundTouch WWW: http://www.surina.net/soundtouch +/// +//////////////////////////////////////////////////////////////////////////////// +// +// Last changed : $Date: 2006/02/05 16:44:06 $ +// File revision : $Revision: 1.9 $ +// +// $Id: AAFilter.cpp,v 1.9 2006/02/05 16:44:06 Olli Exp $ +// +//////////////////////////////////////////////////////////////////////////////// +// +// License : +// +// SoundTouch audio processing library +// Copyright (c) Olli Parviainen +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//////////////////////////////////////////////////////////////////////////////// + +#include <memory.h> +#include <assert.h> +#include <math.h> +#include <stdlib.h> +#include "AAFilter.h" +#include "FIRFilter.h" + +using namespace soundtouch; + +#define PI 3.141592655357989 +#define TWOPI (2 * PI) + +/***************************************************************************** + * + * Implementation of the class 'AAFilter' + * + *****************************************************************************/ + +AAFilter::AAFilter(const uint length) +{ + pFIR = FIRFilter::newInstance(); + cutoffFreq = 0.5; + setLength(length); +} + + + +AAFilter::~AAFilter() +{ + delete pFIR; +} + + + +// Sets new anti-alias filter cut-off edge frequency, scaled to +// sampling frequency (nyquist frequency = 0.5). +// The filter will cut frequencies higher than the given frequency. +void AAFilter::setCutoffFreq(const double newCutoffFreq) +{ + cutoffFreq = newCutoffFreq; + calculateCoeffs(); +} + + + +// Sets number of FIR filter taps +void AAFilter::setLength(const uint newLength) +{ + length = newLength; + calculateCoeffs(); +} + + + +// Calculates coefficients for a low-pass FIR filter using Hamming window +void AAFilter::calculateCoeffs() +{ + uint i; + double cntTemp, temp, tempCoeff,h, w; + double fc2, wc; + double scaleCoeff, sum; + double *work; + SAMPLETYPE *coeffs; + + assert(length > 0); + assert(length % 4 == 0); + assert(cutoffFreq >= 0); + assert(cutoffFreq <= 0.5); + + work = new double[length]; + coeffs = new SAMPLETYPE[length]; + + fc2 = 2.0 * cutoffFreq; + wc = PI * fc2; + tempCoeff = TWOPI / (double)length; + + sum = 0; + for (i = 0; i < length; i ++) + { + cntTemp = (double)i - (double)(length / 2); + + temp = cntTemp * wc; + if (temp != 0) + { + h = fc2 * sin(temp) / temp; // sinc function + } + else + { + h = 1.0; + } + w = 0.54 + 0.46 * cos(tempCoeff * cntTemp); // hamming window + + temp = w * h; + work[i] = temp; + + // calc net sum of coefficients + sum += temp; + } + + // ensure the sum of coefficients is larger than zero + assert(sum > 0); + + // ensure we've really designed a lowpass filter... + assert(work[length/2] > 0); + assert(work[length/2 + 1] > -1e-6); + assert(work[length/2 - 1] > -1e-6); + + // Calculate a scaling coefficient in such a way that the result can be + // divided by 16384 + scaleCoeff = 16384.0f / sum; + + for (i = 0; i < length; i ++) + { + // scale & round to nearest integer + temp = work[i] * scaleCoeff; + temp += (temp >= 0) ? 0.5 : -0.5; + // ensure no overfloods + assert(temp >= -32768 && temp <= 32767); + coeffs[i] = (SAMPLETYPE)temp; + } + + // Set coefficients. Use divide factor 14 => divide result by 2^14 = 16384 + pFIR->setCoefficients(coeffs, length, 14); + + delete[] work; + delete[] coeffs; +} + + +// Applies the filter to the given sequence of samples. +// Note : The amount of outputted samples is by value of 'filter length' +// smaller than the amount of input samples. +uint AAFilter::evaluate(SAMPLETYPE *dest, const SAMPLETYPE *src, uint numSamples, uint numChannels) const +{ + return pFIR->evaluate(dest, src, numSamples, numChannels); +} + + +uint AAFilter::getLength() const +{ + return pFIR->getLength(); +} Added: trunk/OpenMPT/soundtouch/AAFilter.h =================================================================== --- trunk/OpenMPT/soundtouch/AAFilter.h (rev 0) +++ trunk/OpenMPT/soundtouch/AAFilter.h 2008-10-13 14:25:58 UTC (rev 227) @@ -0,0 +1,91 @@ +//////////////////////////////////////////////////////////////////////////////// +/// +/// Sampled sound tempo changer/time stretch algorithm. Changes the sound tempo +/// while maintaining the original pitch by using a time domain WSOLA-like method +/// with several performance-increasing tweaks. +/// +/// Anti-alias filter is used to prevent folding of high frequencies when +/// transposing the sample rate with interpolation. +/// +/// Author : Copyright (c) Olli Parviainen +/// Author e-mail : oparviai 'at' iki.fi +/// SoundTouch WWW: http://www.surina.net/soundtouch +/// +//////////////////////////////////////////////////////////////////////////////// +// +// Last changed : $Date: 2006/02/05 16:44:06 $ +// File revision : $Revision: 1.10 $ +// +// $Id: AAFilter.h,v 1.10 2006/02/05 16:44:06 Olli Exp $ +// +//////////////////////////////////////////////////////////////////////////////// +// +// License : +// +// SoundTouch audio processing library +// Copyright (c) Olli Parviainen +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef AAFilter_H +#define AAFilter_H + +#include "STTypes.h" + +namespace soundtouch +{ + +class AAFilter +{ +protected: + class FIRFilter *pFIR; + + /// Low-pass filter cut-off frequency, negative = invalid + double cutoffFreq; + + /// num of filter taps + uint length; + + /// Calculate the FIR coefficients realizing the given cutoff-frequency + void calculateCoeffs(); +public: + AAFilter(uint length); + + ~AAFilter(); + + /// Sets new anti-alias filter cut-off edge frequency, scaled to sampling + /// frequency (nyquist frequency = 0.5). The filter will cut off the + /// frequencies than that. + void setCutoffFreq(double newCutoffFreq); + + /// Sets number of FIR filter taps, i.e. ~filter complexity + void setLength(uint newLength); + + uint getLength() const; + + /// Applies the filter to the given sequence of samples. + /// Note : The amount of outputted samples is by value of 'filter length' + /// smaller than the amount of input samples. + uint evaluate(SAMPLETYPE *dest, + const SAMPLETYPE *src, + uint numSamples, + uint numChannels) const; +}; + +} + +#endif Added: trunk/OpenMPT/soundtouch/BPMDetect.h =================================================================== --- trunk/OpenMPT/soundtouch/BPMDetect.h (rev 0) +++ trunk/OpenMPT/soundtouch/BPMDetect.h 2008-10-13 14:25:58 UTC (rev 227) @@ -0,0 +1,159 @@ +//////////////////////////////////////////////////////////////////////////////// +/// +/// Beats-per-minute (BPM) detection routine. +/// +/// The beat detection algorithm works as follows: +/// - Use function 'inputSamples' to input a chunks of samples to the class for +/// analysis. It's a good idea to enter a large sound file or stream in smallish +/// chunks of around few kilosamples in order not to extinguish too much RAM memory. +/// - Input sound data is decimated to approx 500 Hz to reduce calculation burden, +/// which is basically ok as low (bass) frequencies mostly determine the beat rate. +/// Simple averaging is used for anti-alias filtering because the resulting signal +/// quality isn't of that high importance. +/// - Decimated sound data is enveloped, i.e. the amplitude shape is detected by +/// taking absolute value that's smoothed by sliding average. Signal levels that +/// are below a couple of times the general RMS amplitude level are cut away to +/// leave only notable peaks there. +/// - Repeating sound patterns (e.g. beats) are detected by calculating short-term +/// autocorrelation function of the enveloped signal. +/// - After whole sound data file has been analyzed as above, the bpm level is +/// detected by function 'getBpm' that finds the highest peak of the autocorrelation +/// function, calculates it's precise location and converts this reading to bpm's. +/// +/// Author : Copyright (c) Olli Parviainen +/// Author e-mail : oparviai 'at' iki.fi +/// SoundTouch WWW: http://www.surina.net/soundtouch +/// +//////////////////////////////////////////////////////////////////////////////// +// +// Last changed : $Date: 2006/02/05 16:44:06 $ +// File revision : $Revision: 1.5 $ +// +// $Id: BPMDetect.h,v 1.5 2006/02/05 16:44:06 Olli Exp $ +// +//////////////////////////////////////////////////////////////////////////////// +// +// License : +// +// SoundTouch audio processing library +// Copyright (c) Olli Parviainen +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//////////////////////////////////////////////////////////////////////////////// + +#ifndef _BPMDetect_H_ +#define _BPMDetect_H_ + +#include "STTypes.h" +#include "FIFOSampleBuffer.h" + +/// Minimum allowed BPM rate. Used to restrict accepted result above a reasonable limit. +#define MIN_BPM 45 + +/// Maximum allowed BPM rate. Used to restrict accepted result below a reasonable limit. +#define MAX_BPM 230 + + +/// Class for calculating BPM rate for audio data. +class BPMDetect +{ +protected: + /// Auto-correlation accumulator bins. + float *xcorr; + + /// Amplitude envelope sliding average approximation level accumulator + float envelopeAccu; + + /// RMS volume sliding average approximation level accumulator + float RMSVolumeAccu; + + /// Sample average counter. + int decimateCount; + + /// Sample average accumulator for FIFO-like decimation. + soundtouch::LONG_SAMPLETYPE decimateSum; + + /// Decimate sound by this coefficient to reach approx. 500 Hz. + int decimateBy; + + /// Auto-correlation window length + int windowLen; + + /// Number of channels (1 = mono, 2 = stereo) + int channels; + + /// sample rate + int sampleRate; + + /// Beginning of auto-correlation window: Autocorrelation isn't being updated for + /// the first these many correlation bins. + int windowStart; + + /// FIFO-buffer for decimated processing samples. + soundtouch::FIFOSampleBuffer *buffer; + + /// Initialize the class for processing. + void init(int numChannels, int sampleRate); + + /// Updates auto-correlation function for given number of decimated samples that + /// are read from the internal 'buffer' pipe (samples aren't removed from the pipe + /// though). + void updateXCorr(int process_samples /// How many samples are processed. + ); + + /// Decimates samples to approx. 500 Hz. + /// + /// \return Number of output samples. + int decimate(soundtouch::SAMPLETYPE *dest, ///< Destination buffer + const soundtouch::SAMPLETYPE *src, ///< Source sample buffer + int numsamples ///< Number of source samples. + ); + + /// Calculates amplitude envelope for the buffer of samples. + /// Result is output to 'samples'. + void calcEnvelope(soundtouch::SAMPLETYPE *samples, ///< Pointer to input/output data buffer + int numsamples ///< Number of samples in buffer + ); + +public: + /// Constructor. + BPMDetect(int numChannels, ///< Number of channels in sample data. + int sampleRate ///< Sample rate in Hz. + ); + + /// Destructor. + virtual ~BPMDetect(); + + /// Inputs a block of samples for analyzing: Envelopes the samples and then + /// updates the autocorrelation estimation. When whole song data has been input + /// in smaller blocks using this function, read the resulting bpm with 'getBpm' + /// function. + /// + /// Notice that data in 'samples' array can be disrupted in processing. + void inputSamples(soundtouch::SAMPLETYPE *samples, ///< Pointer to input/working data buffer + int numSamples ///< Number of samples in buffer + ); + + + /// Analyzes the results and returns the BPM rate. Use this function to read result + /// after whole song data has been input to the class by consecutive calls of + /// 'inputSamples' function. + /// + /// \return Beats-per-minute rate, or zero if detection failed. + float getBpm(); +}; + +#endif // _BPMDetect_H_ Added: trunk/OpenMPT/soundtouch/COPYING.TXT =================================================================== --- trunk/OpenMPT/soundtouch/COPYING.TXT (rev 0) +++ trunk/OpenMPT/soundtouch/COPYING.TXT 2008-10-13 14:25:58 UTC (rev 227) @@ -0,0 +1,458 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS Added: trunk/OpenMPT/soundtouch/FIFOSampleBuffer.cpp =================================================================== --- trunk/OpenMPT/soundtouch/FIFOSampleBuffer.cpp (rev 0) +++ trunk/OpenMPT/soundtouch/FIFOSampleBuffer.cpp 2008-10-13 14:25:58 UTC (rev 227) @@ -0,0 +1,252 @@ +//////////////////////////////////////////////////////////////////////////////// +/// +/// A buffer class for temporarily storaging sound samples, operates as a +/// first-in-first-out pipe. +/// +/// Samples are added to the end of the sample buffer with the 'putSamples' +/// function, and are received from the beginning of the buffer by calling +/// the 'receiveSamples' function. The class automatically removes the +/// outputted samples from the buffer, as well as grows the buffer size +/// whenever necessary. +/// +/// Author : Copyright (c) Olli Parviainen +/// Author e-mail : oparviai 'at' iki.fi +/// SoundTouch WWW: http://www.surina.net/soundtouch +/// +//////////////////////////////////////////////////////////////////////////////// +// +// Last changed : $Date: 2006/02/05 16:44:06 $ +// File revision : $Revision: 1.11 $ +// +// $Id: FIFOSampleBuffer.cpp,v 1.11 2006/02/05 16:44:06 Olli Exp $ +// +//////////////////////////////////////////////////////////////////////////////// +// +// License : +// +// SoundTouch audio processing library +// Copyright (c) Olli Parviainen +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +//////////////////////////////////////////////////////////////////////////////// + +#include <stdlib.h> +#include <memory.h> +#include <string.h> +#include <assert.h> +#include <stdexcept> + +#include "FIFOSampleBuffer.h" + +using namespace soundtouch; + +// Constructor +FIFOSampleBuffer::FIFOSampleBuffer(uint numChannels) +{ + sizeInBytes = 0; // reasonable initial value + buffer = NULL; //new SAMPLETYPE[sizeInBytes / sizeof(SAMPLETYPE)]; + bufferUnaligned = NULL; + samplesInBuffer = 0; + bufferPos = 0; + channels = numChannels; +} + + +// destructor +FIFOSampleBuffer::~FIFOSampleBuffer() +{ + delete[] bufferUnaligned; +} + + +// Sets number of channels, 1 = mono, 2 = stereo +void FIFOSampleBuffer::setChannels(const uint numChannels) +{ + uint usedBytes; + + usedBytes = channels * samplesInBuffer; + channels = numChannels; + samplesInBuffer = usedBytes / channels; +} + + +// if output location pointer 'bufferPos' isn't zero, 'rewinds' the buffer and +// zeroes this pointer by copying samples from the 'bufferPos' pointer +// location on to the beginning of the buffer. +void FIFOSampleBuffer::rewind() +{ + if (bufferPos) + { + memmove(buffer, ptrBegin(), sizeof(SAMPLETYPE) * channels * samplesInBuffer); + bufferPos = 0; + } +} + + +// Adds 'numSamples' pcs of samples from the 'samples' memory position to +// the sample buffer. +void FIFOSampleBuffer::putSamples(const SAMPLETYPE *samples, uint numSamples) +{ + memcpy(ptrEnd(numSamples), samples, sizeof(SAMPLETYPE) * numSamples * channels); + samplesInBuffer += numSamples; +} + + +// Increases the number of samples in the buffer without copying any actual +// samples. +// +// This function is used to update the number of samples in the sample buffer +// when accessing the buffer directly with 'ptrEnd' function. Please be +// careful though! +void FIFOSampleBuffer::putSamples(uint numSamples) +{ + uint req; + + req = samplesInBuffer + numSamples; + ensureCapacity(req); + samplesInBuffer += numSamples; +} + + +// Returns a pointer to the end of the used part of the sample buffer (i.e. +// where the new samples are to be inserted). This function may be used for +// inserting new samples into the sample buffer directly. Please be careful! +// +// Parameter 'slackCapacity' tells the function how much free capacity (in +// terms of samples) there _at least_ should be, in order to the caller to +// succesfully insert all the required samples to the buffer. When necessary, +// the function grows the buffer size to comply with this requirement. +// +// When using this function as means for inserting new samples, also remember +// to increase the sample count afterwards, by calling the +// 'putSamples(numSamples)' function. +SAMPLETYPE *FIFOSampleBuffer::ptrEnd(uint slackCapacity) +{ + ensureCapacity(samplesInBuffer + slackCapacity); + return buffer + samplesInBuffer * channels; +} + + +// Returns a pointer to the beginning of the currently non-outputted samples. +// This function is provided for accessing the output samples directly. +// Please be careful! +// +// When using this function to output samples, also remember to 'remove' the +// outputted samples from the buffer by calling the +// 'receiveSamples(numSamples)' function +SAMPLETYPE *FIFOSampleBuffer::ptrBegin() const +{ + return buffer + bufferPos * channels; +} + + +// Ensures that the buffer has enought capacity, i.e. space for _at least_ +// 'capacityRequirement' number of samples. The buffer is grown in steps of +// 4 kilobytes to eliminate the need for frequently growing up the buffer, +// as well as to round the buffer size up to the virtual memory page size. +void FIFOSampleBuffer::ensureCapacity(uint capacityRequirement) +{ + SAMPLETYPE *tempUnaligned, *temp; + + if (capacityRequirement > getCapacity()) + { + // enlarge the buffer in 4kbyte steps (round up to next 4k boundary) + sizeInBytes = (capacityRequirement * channels * sizeof(SAMPLETYPE) + 4095) & -4096; + assert(sizeInBytes % 2 == 0); + tempUnaligned = new SAMPLETYPE[sizeInBytes / sizeof(SAMPLETYPE) + 16 / sizeof(SAMPLETYPE)]; + if (tempUnaligned == NULL) + { + throw std::runtime_error("Couldn't allocate memory!\n"); + } + temp = (SAMPLETYPE *)(((ulong)tempUnaligned + 15) & -16); + memcpy(temp, ptrBegin(), samplesInBuffer * channels * sizeof(SAMPLETYPE)); + delete[] bufferUnaligned; + buffer = temp; + bufferUnaligned = tempUnaligned; + bufferPos = 0; + } + else + { + // simply rewind the buffer (if necessary) + rewind(); + } +} + + +// Returns the current buffer capacity in terms of samples +uint FIFOSampleBuffer::getCapacity() const +{ +... [truncated message content] |
From: <rel...@us...> - 2008-10-13 15:19:24
|
Revision: 228 http://modplug.svn.sourceforge.net/modplug/?rev=228&view=rev Author: relabsoluness Date: 2008-10-13 15:19:08 +0000 (Mon, 13 Oct 2008) Log Message: ----------- / PitchShift and time stretching are back. PitchShift wasn't affected by the license problem so its back as it was, and time stretching is now implemented with SoundTouch-library. SoundTouch is used from delay loaded DLL so the main program should work even if the library is not available. / Pitchshifting/Time Stretching of 8-bit samples is now disabled (didn't seem to work). + A few new methods added to MODINSTRUMENT for readability and easier usage. / Restored default orderlist margins to two. + Added new inisetting that can be used to show/hide some hack GUI controls. / Rearranged control tab order in sample control to make tooltips work in it(don't know why it matters). / mptrack now produces program database(pdb-file) also on release build. Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_pat.cpp trunk/OpenMPT/mptrack/Ctrl_pat.h trunk/OpenMPT/mptrack/Ctrl_smp.cpp trunk/OpenMPT/mptrack/Ctrl_smp.h trunk/OpenMPT/mptrack/MPTRACK.sln trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Mainfrm.h trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/mptrack/mptrack.vcproj trunk/OpenMPT/mptrack/res/MPTRACK.RC2 trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/mptrack/Ctrl_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2008-10-13 14:25:58 UTC (rev 227) +++ trunk/OpenMPT/mptrack/Ctrl_pat.cpp 2008-10-13 15:19:08 UTC (rev 228) @@ -13,7 +13,6 @@ ////////////////////////////////////////////////////////////// // CCtrlPatterns -bool CCtrlPatterns::s_ShowSequenceMarginsControls = false; BEGIN_MESSAGE_MAP(CCtrlPatterns, CModControlDlg) //{{AFX_MSG_MAP(CCtrlPatterns) @@ -172,7 +171,7 @@ m_SpinInstrument.SetRange(-1, 1); m_SpinInstrument.SetPos(0); - if(s_ShowSequenceMarginsControls == true) + if(CMainFrame::gbShowHackControls == true) { m_SpinOrderListMargins.ShowWindow(SW_SHOW); m_EditOrderListMargins.ShowWindow(SW_SHOW); Modified: trunk/OpenMPT/mptrack/Ctrl_pat.h =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_pat.h 2008-10-13 14:25:58 UTC (rev 227) +++ trunk/OpenMPT/mptrack/Ctrl_pat.h 2008-10-13 15:19:08 UTC (rev 228) @@ -144,9 +144,6 @@ // -! NEW_FEATURE#0012 public: - static bool s_ShowSequenceMarginsControls; - -public: CCtrlPatterns(); LONG* GetSplitPosRef() {return &CMainFrame::glPatternWindowHeight;} //rewbs.varWindowSize Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2008-10-13 14:25:58 UTC (rev 227) +++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2008-10-13 15:19:08 UTC (rev 228) @@ -9,10 +9,14 @@ #include "dlg_misc.h" #include "PSRatioCalc.h" //rewbs.timeStretchMods #include "mpdlgs.h" +#include "soundtouch/SoundTouch.h" +#include "soundtouch/TDStretch.h" +#pragma warning(disable:4244) //"conversion from 'type1' to 'type2', possible loss of data" +#include "smbPitchShift.cpp" +#pragma warning(default:4244) //"conversion from 'type1' to 'type2', possible loss of data" -#ifndef NO_XSOUNDLIB - #include "smbPitchShift.h" - #include "samplerate.h" +#ifdef _DEBUG + #define new DEBUG_NEW #endif #ifdef _DEBUG @@ -64,15 +68,11 @@ ON_COMMAND(IDC_CHECK1, OnSetPanningChanged) ON_COMMAND(ID_PREVINSTRUMENT, OnPrevInstrument) ON_COMMAND(ID_NEXTINSTRUMENT, OnNextInstrument) - -#ifndef NO_XSOUNDLIB ON_COMMAND(IDC_BUTTON1, OnPitchShiftTimeStretch) ON_COMMAND(IDC_BUTTON2, OnEstimateSampleSize) ON_COMMAND(IDC_BUTTON3, OnPitchShiftTimeStretchAccept) ON_COMMAND(IDC_BUTTON4, OnPitchShiftTimeStretchCancel) ON_COMMAND(IDC_CHECK3, OnEnableStretchToSize) -#endif - ON_EN_CHANGE(IDC_SAMPLE_NAME, OnNameChanged) ON_EN_CHANGE(IDC_SAMPLE_FILENAME, OnFileNameChanged) ON_EN_CHANGE(IDC_EDIT_SAMPLE, OnSampleChanged) @@ -138,43 +138,39 @@ DDX_Control(pDX, IDC_EDIT14, m_EditVibSweep); DDX_Control(pDX, IDC_EDIT15, m_EditVibDepth); DDX_Control(pDX, IDC_EDIT16, m_EditVibRate); - -#ifndef NO_XSOUNDLIB DDX_Control(pDX, IDC_COMBO4, m_ComboPitch); DDX_Control(pDX, IDC_COMBO5, m_ComboQuality); DDX_Control(pDX, IDC_COMBO6, m_ComboFFT); DDX_Text(pDX, IDC_EDIT6, m_dTimeStretchRatio); //rewbs.timeStretchMods -#endif - //}}AFX_DATA_MAP } -CCtrlSamples::CCtrlSamples() -//-------------------------- +CCtrlSamples::CCtrlSamples() : +//---------------------------- + m_nStretchProcessStepLength(nDefaultStretchChunkSize), + m_nSequenceMs(DEFAULT_SEQUENCE_MS), + m_nSeekWindowMs(DEFAULT_SEEKWINDOW_MS), + m_nOverlapMs(DEFAULT_OVERLAP_MS) { m_nSample = 1; m_nLockCount = 1; - -#ifndef NO_XSOUNDLIB pSampleUndoBuffer = NULL; UndoBufferSize = 0; -#endif - } -#ifndef NO_XSOUNDLIB - CCtrlSamples::~CCtrlSamples() - { - if(pSampleUndoBuffer) CSoundFile::FreeSample(pSampleUndoBuffer); - pSampleUndoBuffer = NULL; - UndoBufferSize = 0; - } -#endif +CCtrlSamples::~CCtrlSamples() +//--------------------------- +{ + if(pSampleUndoBuffer) CSoundFile::FreeSample(pSampleUndoBuffer); + pSampleUndoBuffer = NULL; + UndoBufferSize = 0; +} + CRuntimeClass *CCtrlSamples::GetAssociatedViewClass() //--------------------------------------------------- { @@ -241,7 +237,6 @@ } -#ifndef NO_XSOUNDLIB m_ComboFFT.ShowWindow(SW_SHOW); m_ComboPitch.ShowWindow(SW_SHOW); m_ComboQuality.ShowWindow(SW_SHOW); @@ -315,7 +310,6 @@ // Stretch to size check box OnEnableStretchToSize(); -#endif // NO_XSOUNDLIB return TRUE; } @@ -337,9 +331,7 @@ if (pSndFile->m_nSamples < 1) pSndFile->m_nSamples = 1; if ((nSmp < 1) || (nSmp > pSndFile->m_nSamples)) return FALSE; -#ifndef NO_XSOUNDLIB if(pSampleUndoBuffer) OnPitchShiftTimeStretchCancel(); -#endif LockControls(); if (m_nSample != nSmp) @@ -511,6 +503,9 @@ return TRUE; } break; + case IDC_EDIT_STRETCHPARAMS: + wsprintf(pszText, "SequenceMs SeekwindowMs OverlapMs ProcessStepLength"); + return TRUE; } } return FALSE; @@ -683,11 +678,8 @@ DWORD len; BOOL bOk; -#ifndef NO_XSOUNDLIB if(pSampleUndoBuffer) OnPitchShiftTimeStretchCancel(); -#endif - BeginWaitCursor(); if ((!lpszFileName) || (!f.Open(lpszFileName))) { @@ -803,11 +795,8 @@ { if ((!pSndFile) || (!nSample) || (nSample > pSndFile->m_nSamples)) return FALSE; -#ifndef NO_XSOUNDLIB if(pSampleUndoBuffer) OnPitchShiftTimeStretchCancel(); -#endif - BeginWaitCursor(); BEGIN_CRITICAL(); m_pSndFile->DestroySample(m_nSample); @@ -835,10 +824,7 @@ { if ((!IsLocked()) && (m_pSndFile)) { - -#ifndef NO_XSOUNDLIB if(pSampleUndoBuffer) OnPitchShiftTimeStretchCancel(); -#endif UINT n = GetDlgItemInt(IDC_EDIT_SAMPLE); if ((n > 0) && (n <= m_pSndFile->m_nSamples) && (n != m_nSample)) @@ -878,10 +864,7 @@ LONG smp = m_pModDoc->InsertSample(TRUE); if (smp > 0) { - - #ifndef NO_XSOUNDLIB if(pSampleUndoBuffer) OnPitchShiftTimeStretchCancel(); - #endif CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); SetCurrentSample(smp); @@ -1431,25 +1414,68 @@ } -#ifndef NO_XSOUNDLIB - #define MAX_BUFFER_LENGTH 8192 #define CLIP_SOUND(v) v = v < -1.0f ? -1.0f : v > 1.0f ? 1.0f : v +void CCtrlSamples::ReadTimeStretchParameters() +//-------------------------------------------- +{ + CString str; + GetDlgItemText(IDC_EDIT_STRETCHPARAMS, str); + _stscanf(str, __TEXT("%u %u %u %u"), + &m_nSequenceMs, &m_nSeekWindowMs, &m_nOverlapMs, &m_nStretchProcessStepLength); +} + + +void CCtrlSamples::UpdateTimeStretchParameterString() +//--------------------------------------------------- +{ + CString str; + str.Format(__TEXT("%u %u %u %u"), + m_nSequenceMs, + m_nSeekWindowMs, + m_nOverlapMs, + m_nStretchProcessStepLength + ); + SetDlgItemText(IDC_EDIT_STRETCHPARAMS, str); +} + void CCtrlSamples::OnEnableStretchToSize() +//---------------------------------------- { // Enable time-stretching / disable unused pitch-shifting UI elements if(IsDlgButtonChecked(IDC_CHECK3)){ ((CComboBox *)GetDlgItem(IDC_COMBO4))->EnableWindow(FALSE); ((CEdit *)GetDlgItem(IDC_EDIT6))->EnableWindow(TRUE); ((CButton *)GetDlgItem(IDC_BUTTON2))->EnableWindow(TRUE); //rewbs.timeStretchMods + GetDlgItem(IDC_TEXT_QUALITY)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_COMBO5)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_TEXT_FFT)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_COMBO6)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_TEXT_PITCH)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_COMBO4)->ShowWindow(SW_HIDE); + if(CMainFrame::gbShowHackControls == true) + { + GetDlgItem(IDC_TEXT_STRETCHPARAMS)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_EDIT_STRETCHPARAMS)->ShowWindow(SW_SHOW); + } SetDlgItemText(IDC_BUTTON1, "Time Stretch"); + UpdateTimeStretchParameterString(); } // Enable pitch-shifting / disable unused time-stretching UI elements else{ + ReadTimeStretchParameters(); + GetDlgItem(IDC_TEXT_QUALITY)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_COMBO5)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_TEXT_FFT)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_COMBO6)->ShowWindow(SW_SHOW); ((CComboBox *)GetDlgItem(IDC_COMBO4))->EnableWindow(TRUE); ((CEdit *)GetDlgItem(IDC_EDIT6))->EnableWindow(FALSE); ((CButton *)GetDlgItem(IDC_BUTTON2))->EnableWindow(FALSE); //rewbs.timeStretchMods + GetDlgItem(IDC_TEXT_STRETCHPARAMS)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_EDIT_STRETCHPARAMS)->ShowWindow(SW_HIDE); + GetDlgItem(IDC_TEXT_PITCH)->ShowWindow(SW_SHOW); + GetDlgItem(IDC_COMBO4)->ShowWindow(SW_SHOW); SetDlgItemText(IDC_BUTTON1, "Pitch Shift"); } } @@ -1519,11 +1545,14 @@ UpdateData(TRUE); //Ensure m_dTimeStretchRatio is up-to-date with textbox content errorcode = TimeStretch(m_dTimeStretchRatio/100.0); - //Update loop points - pins->nLoopStart *= m_dTimeStretchRatio/100.0; - pins->nLoopEnd *= m_dTimeStretchRatio/100.0; - pins->nSustainStart *= m_dTimeStretchRatio/100.0; - pins->nSustainEnd *= m_dTimeStretchRatio/100.0; + //Update loop points only if no error occured. + if(errorcode == 0) + { + pins->nLoopStart *= m_dTimeStretchRatio/100.0; + pins->nLoopEnd *= m_dTimeStretchRatio/100.0; + pins->nSustainStart *= m_dTimeStretchRatio/100.0; + pins->nSustainEnd *= m_dTimeStretchRatio/100.0; + } //end rewbs.timeStretchMods } @@ -1574,6 +1603,12 @@ break; case 3 : wsprintf(str,"Not enough memory..."); break; + case 4 : wsprintf(str, "Action can be applied only to 16-bit samples."); + break; + case 5 : wsprintf(str, "Too low sample rate"); + break; + case 6 : wsprintf(str, "Too short sample"); + break; default: wsprintf(str,"Unknown Error..."); break; } @@ -1586,6 +1621,7 @@ } void CCtrlSamples::OnPitchShiftTimeStretchAccept() +//------------------------------------------------ { // Free sample undo buffer if(pSampleUndoBuffer) CSoundFile::FreeSample(pSampleUndoBuffer); @@ -1662,12 +1698,25 @@ m_pModDoc->SetModified(); } + int CCtrlSamples::TimeStretch(double ratio) +//----------------------------------------- { if((!m_pSndFile) || (!m_pSndFile->Ins[m_nSample].pSample)) return -1; MODINSTRUMENT *pins = &m_pSndFile->Ins[m_nSample]; if(!pins) return -1; + // Stretching is implemented only for 16-bit samples. Return with + // error if trying to use wtih non 16-bit samples. + if(pins->GetElementarySampleSize() != 2) + return 4; + + // SoundTouch seems to crash with short samples. Don't know what + // the actual limit or whether it depends on sample rate, + // but simply set some semiarbitrary threshold here. + if(pins->nLength < 256) + return 6; + // Refuse processing when ratio is negative, equal to zero or equal to 1.0 if(ratio <= 0.0 || ratio == 1.0) return -1; @@ -1676,42 +1725,31 @@ if(pitch < 0.5f) return 2 + (1<<8); if(pitch > 2.0f) return 2 + (2<<8); + soundtouch::SoundTouch* pSoundTouch = 0; + try + { + pSoundTouch = new soundtouch::SoundTouch; + } + catch(...) + { // Assuming that thrown exception means that soundtouch library could not be loaded. + MessageBox("Failed to load soundtouch library.", 0, MB_ICONERROR); + return -1; + } + // Get number of channels & sample size - BYTE smpsize = (pins->uFlags & CHN_16BIT) ? 2 : 1; - UINT nChn = (pins->uFlags & CHN_STEREO) ? 2 : 1; + const BYTE smpsize = pins->GetElementarySampleSize(); + const UINT nChn = pins->GetNumChannels(); // Allocate new sample - DWORD newsize = (DWORD)(0.5 + ratio * (double)pins->nLength); + const DWORD nNewSampleLength = (DWORD)(0.5 + ratio * (double)pins->nLength); PVOID pSample = pins->pSample; - PVOID pNewSample = CSoundFile::AllocateSample(newsize * nChn * smpsize); - if(pNewSample == NULL) return 3; + PVOID pNewSample = CSoundFile::AllocateSample(nNewSampleLength * nChn * smpsize); + if(pNewSample == NULL) + { + delete pSoundTouch; + return 3; + } - // Apply pitch-shifting step - PitchShift(pitch); - - // Allocate working buffers - UINT outputsize = (UINT)(0.5 + ratio * (double)MAX_BUFFER_LENGTH); - if( (outputsize & 1) && (smpsize == 2 || nChn == 2) ) outputsize++; - - float * buffer = new float[MAX_BUFFER_LENGTH * nChn]; - float * outbuf = new float[outputsize * nChn]; - - // Create resampler - int error; - SRC_STATE * resampler = src_new(SRC_SINC_BEST_QUALITY, nChn, &error) ; - - // Fill in resampler data struct - SRC_DATA data; - data.data_in = &buffer[0]; - data.input_frames = MAX_BUFFER_LENGTH; - data.data_out = &outbuf[0]; - data.output_frames = outputsize; - data.src_ratio = ratio; - data.end_of_input = 0; - - // Deduce max sample value (float conversion step) - float maxSampleValue = ( 1 << (smpsize * 8 - 1) ) - 1; - // Save process button text (to be used as "progress bar" indicator while processing) CHAR oldText[255]; GetDlgItemText(IDC_BUTTON1, oldText, 255); @@ -1732,16 +1770,58 @@ // Show wait mouse cursor BeginWaitCursor(); - SetDlgItemText(IDC_STATIC1,"Resampling..."); + SetDlgItemText(IDC_STATIC1, "Stretching..."); - // Apply stretching (resampling) step - UINT pos = 0, posnew = 0; - UINT len = MAX_BUFFER_LENGTH; + UINT pos = 0; + UINT len = 0; //To contain length of processing step. - // Process sample buffer using MAX_BUFFER_LENGTH (max) sized chunk steps (in order to allow - // the processing of BIG samples...) - while(pos < pins->nLength){ + // Initialize soundtouch object. + { + const uint32 nSampleRate = pins->GetSampleRate(m_pSndFile->GetType()); + if(nSampleRate < 300) // Too low samplerate crashes soundtouch. + { // Limiting it to value 300(quite arbitrarily chosen). + delete pSoundTouch; + return 5; + } + pSoundTouch->setSampleRate(nSampleRate); + pSoundTouch->setChannels(nChn); + // Given ratio is time stretch ratio, and must be converted to + // tempo change ratio: for example time stretch ratio 2 means + // tempo change ratio 0.5. + pSoundTouch->setTempoChange( (1.0f / ratio - 1.0f) * 100.0f); + pSoundTouch->setSetting(SETTING_USE_QUICKSEEK, 0); + // Read settings from GUI. + ReadTimeStretchParameters(); + + if(m_nStretchProcessStepLength == 0) m_nStretchProcessStepLength = nDefaultStretchChunkSize; + if(m_nStretchProcessStepLength < 64) m_nStretchProcessStepLength = nDefaultStretchChunkSize; + len = m_nStretchProcessStepLength; + + // Set settings to soundtouch. Zero value means 'use default', and + // setting value is read back after setting because not all settings are accepted. + if(m_nSequenceMs == 0) m_nSequenceMs = DEFAULT_SEQUENCE_MS; + pSoundTouch->setSetting(SETTING_SEQUENCE_MS, m_nSequenceMs); + m_nSequenceMs = pSoundTouch->getSetting(SETTING_SEQUENCE_MS); + + if(m_nSeekWindowMs == 0) m_nSeekWindowMs = DEFAULT_SEEKWINDOW_MS; + pSoundTouch->setSetting(SETTING_SEEKWINDOW_MS, m_nSeekWindowMs); + m_nSeekWindowMs = pSoundTouch->getSetting(SETTING_SEEKWINDOW_MS); + + if(m_nOverlapMs == 0) m_nOverlapMs = DEFAULT_OVERLAP_MS; + pSoundTouch->setSetting(SETTING_OVERLAP_MS, m_nOverlapMs); + m_nOverlapMs = pSoundTouch->getSetting(SETTING_OVERLAP_MS); + + // Update GUI with the actual SoundTouch parameters in effect. + UpdateTimeStretchParameterString(); + } + + // Keeps count of the sample length received from stretching process. + UINT nLengthCounter = 0; + + // Process sample in steps. + while(pos < pins->nLength) + { // Current chunk size limit test if(pos + len >= pins->nLength) len = pins->nLength - pos; @@ -1759,58 +1839,26 @@ ::DrawText(processButtonDC,progress,strlen(progress),&processButtonRect,DT_CENTER | DT_SINGLELINE | DT_VCENTER); ::GdiFlush(); - // Convert current channel's data chunk to float - BYTE * ptr = (BYTE *)pSample + pos * smpsize * nChn; + // Send sampledata for processing. + pSoundTouch->putSamples(reinterpret_cast<int16*>(pins->pSample + pos * smpsize * nChn), len); - for(UINT j = 0 ; j < len ; j++){ - switch(smpsize){ - case 2: - buffer[j*nChn] = ((float)(*(SHORT *)ptr)) / maxSampleValue; - if(nChn == 2) { ptr += 2; buffer[j*nChn+1] = ((float)(*(SHORT *)ptr)) / maxSampleValue; } - break; - case 1: - buffer[j*nChn] = ((float)*ptr) / maxSampleValue; - if(nChn == 2) { ptr++; buffer[j*nChn+1] = ((float)*ptr) / maxSampleValue; } - break; - } - ptr += smpsize; - } + // Receive some processed samples (it's not guaranteed that there is any available). + nLengthCounter += pSoundTouch->receiveSamples(reinterpret_cast<int16*>(pNewSample) + nChn * nLengthCounter, nNewSampleLength - nLengthCounter); - // Wake up resampler... - if(pos + MAX_BUFFER_LENGTH >= pins->nLength) data.end_of_input = 1; - src_process(resampler, &data); - - // New buffer limit test (seems like, whatever the size of the last chunk, the resampler return buffer size instead of processed size) - if(data.end_of_input && posnew + (UINT)data.output_frames_gen >= newsize) data.output_frames_gen = newsize - posnew; - - // Convert resampled float buffer into new sample buffer - ptr = (BYTE *)pNewSample + posnew * smpsize * nChn; - - for(UINT j = 0 ; j < (UINT)data.output_frames_gen ; j++){ - // Just perform a little bit of clipping... - float v = outbuf[j*nChn]; CLIP_SOUND(v); - // ...before converting back to buffer - switch(smpsize){ - case 2: - *(SHORT *)ptr = (SHORT)(v * maxSampleValue); - if(nChn == 2) { ptr += 2; v = outbuf[j*nChn+1]; CLIP_SOUND(v); *(SHORT *)ptr = (SHORT)(v * maxSampleValue); } - break; - case 1: - *ptr = (BYTE)(v * maxSampleValue); - if(nChn == 2) { ptr++; v = outbuf[j*nChn+1]; CLIP_SOUND(v); *ptr = (BYTE)(v * maxSampleValue); } - break; - } - ptr += smpsize; - } - // Next buffer chunk - posnew += data.output_frames_gen; - pos += MAX_BUFFER_LENGTH; + pos += len; } - // Update newsize with generated size - newsize = posnew; + // The input sample should now be processed. Receive remaining samples. + pSoundTouch->flush(); + while(pSoundTouch->numSamples() > 0 && nNewSampleLength > nLengthCounter) + { + nLengthCounter += pSoundTouch->receiveSamples(reinterpret_cast<int16*>(pNewSample) + nChn * nLengthCounter, nNewSampleLength - nLengthCounter); + } + delete pSoundTouch; pSoundTouch = 0; + ASSERT(nNewSampleLength >= nLengthCounter); + // Swap sample buffer pointer to new buffer, update song + sample data & free old sample buffer BEGIN_CRITICAL(); for(UINT i=0 ; i < MAX_CHANNELS ; i++){ @@ -1822,17 +1870,9 @@ } pins->pSample = (LPSTR)pNewSample; CSoundFile::FreeSample(pSample); - pins->nLength = newsize; + pins->nLength = min(nLengthCounter, nNewSampleLength); END_CRITICAL(); - // Free working buffers - data.data_in = data.data_out = NULL; - if(buffer) delete [] buffer; - if(outbuf) delete [] outbuf; - - // Free resampler - if(resampler) src_delete(resampler); - // Free progress bar brushes DeleteObject((HBRUSH)green); DeleteObject((HBRUSH)red); @@ -1848,6 +1888,7 @@ } int CCtrlSamples::PitchShift(float pitch) +//--------------------------------------- { if((!m_pSndFile) || (!m_pSndFile->Ins[m_nSample].pSample)) return -1; if(pitch < 0.5f) return 1 + (1<<8); @@ -1857,6 +1898,11 @@ MODINSTRUMENT *pins = &m_pSndFile->Ins[m_nSample]; if(!pins) return 2; + // PitchShift seems to work only with 16-bit samples. Return with + // error if trying to use non 16-bit samples. + if(pins->GetElementarySampleSize() != 2) + return 4; + // Get number of channels & sample size BYTE smpsize = (pins->uFlags & CHN_16BIT) ? 2 : 1; UINT nChn = (pins->uFlags & CHN_STEREO) ? 2 : 1; @@ -2013,9 +2059,7 @@ return 0; } -#endif // NO_XSOUNDLIB - void CCtrlSamples::OnReverse() //---------------------------- { Modified: trunk/OpenMPT/mptrack/Ctrl_smp.h =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.h 2008-10-13 14:25:58 UTC (rev 227) +++ trunk/OpenMPT/mptrack/Ctrl_smp.h 2008-10-13 15:19:08 UTC (rev 228) @@ -1,10 +1,7 @@ #ifndef _CONTROL_SAMPLES_H_ #define _CONTROL_SAMPLES_H_ -// If defined, disables pitch shifting - time stretching. -#define NO_XSOUNDLIB - //======================================= class CCtrlSamples: public CModControlDlg //======================================= @@ -22,25 +19,25 @@ CButton m_CheckPanning; UINT m_nSample; double m_dTimeStretchRatio; //rewbs.timeStretchMods - + uint32 m_nStretchProcessStepLength; + uint32 m_nSequenceMs; + uint32 m_nSeekWindowMs; + uint32 m_nOverlapMs; + enum {nDefaultStretchChunkSize = 8192}; -#ifndef NO_XSOUNDLIB CComboBox m_ComboPitch, m_ComboQuality, m_ComboFFT; PVOID pSampleUndoBuffer; UINT UndoBufferSize; int PitchShift(float pitch); int TimeStretch(double ratio); -#endif + void UpdateTimeStretchParameterString(); + void ReadTimeStretchParameters(); public: CCtrlSamples(); - -#ifndef NO_XSOUNDLIB ~CCtrlSamples(); -#endif -public: BOOL SetCurrentSample(UINT n, LONG lZoom=-1, BOOL bUpdNum=TRUE); BOOL OpenSample(LPCSTR lpszFileName); BOOL OpenSample(CSoundFile *pSndFile, UINT nSample); @@ -96,13 +93,11 @@ afx_msg void OnVScroll(UINT, UINT, CScrollBar *); afx_msg LRESULT OnCustomKeyMsg(WPARAM, LPARAM); //rewbs.customKeys -#ifndef NO_XSOUNDLIB afx_msg void OnPitchShiftTimeStretch(); afx_msg void OnEnableStretchToSize(); afx_msg void OnEstimateSampleSize(); afx_msg void OnPitchShiftTimeStretchAccept(); afx_msg void OnPitchShiftTimeStretchCancel(); -#endif //}}AFX_MSG DECLARE_MESSAGE_MAP() Modified: trunk/OpenMPT/mptrack/MPTRACK.sln =================================================================== --- trunk/OpenMPT/mptrack/MPTRACK.sln 2008-10-13 14:25:58 UTC (rev 227) +++ trunk/OpenMPT/mptrack/MPTRACK.sln 2008-10-13 15:19:08 UTC (rev 228) @@ -3,6 +3,7 @@ ProjectSection(ProjectDependencies) = postProject {1FF4AB04-B22F-4CB8-AA2A-0C5095B5FEE4} = {1FF4AB04-B22F-4CB8-AA2A-0C5095B5FEE4} {71531076-78C7-488D-8FD6-9D841F20AADE} = {71531076-78C7-488D-8FD6-9D841F20AADE} + {CF3C2CA5-5D45-4635-BBA4-C1F435E10896} = {CF3C2CA5-5D45-4635-BBA4-C1F435E10896} {3C7281B0-D0E2-48ED-AE4D-A181FC77D8F7} = {3C7281B0-D0E2-48ED-AE4D-A181FC77D8F7} EndProjectSection EndProject @@ -22,6 +23,10 @@ ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "soundtouch", "..\soundtouch\soundtouch.vcproj", "{CF3C2CA5-5D45-4635-BBA4-C1F435E10896}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug @@ -50,6 +55,10 @@ {DCC2BB2F-6778-4FD3-9C00-D6CD8DC917B8}.Debug.Build.0 = Debug|Win32 {DCC2BB2F-6778-4FD3-9C00-D6CD8DC917B8}.Release.ActiveCfg = Release|Win32 {DCC2BB2F-6778-4FD3-9C00-D6CD8DC917B8}.Release.Build.0 = Release|Win32 + {CF3C2CA5-5D45-4635-BBA4-C1F435E10896}.Debug.ActiveCfg = Debug|Win32 + {CF3C2CA5-5D45-4635-BBA4-C1F435E10896}.Debug.Build.0 = Debug|Win32 + {CF3C2CA5-5D45-4635-BBA4-C1F435E10896}.Release.ActiveCfg = Release|Win32 + {CF3C2CA5-5D45-4635-BBA4-C1F435E10896}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2008-10-13 14:25:58 UTC (rev 227) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2008-10-13 15:19:08 UTC (rev 228) @@ -133,6 +133,7 @@ UINT CMainFrame::m_nFilterIndex = 0; UINT CMainFrame::m_nLastOptionsPage = 0; BOOL CMainFrame::gbMdiMaximize = FALSE; +bool CMainFrame::gbShowHackControls = false; //rewbs.varWindowSize LONG CMainFrame::glCtrlWindowHeight = 188; //obsolete, for backwards compat only LONG CMainFrame::glGeneralWindowHeight = 178; @@ -427,8 +428,8 @@ gbPatternPluginNames = GetPrivateProfileDWord("Pattern Editor", "Plugin-Names", true, iniFile); gbPatternRecord = GetPrivateProfileDWord("Pattern Editor", "Record", true, iniFile); gnAutoChordWaitTime = GetPrivateProfileDWord("Pattern Editor", "AutoChordWaitTime", 60, iniFile); - CCtrlPatterns::s_ShowSequenceMarginsControls = (0 != GetPrivateProfileDWord("Pattern Editor", "ShowSequenceMarginsControls", 0, iniFile)); - COrderList::s_nDefaultMargins = static_cast<BYTE>(GetPrivateProfileInt("Pattern Editor", "DefaultSequenceMargins", 0, iniFile)); + COrderList::s_nDefaultMargins = static_cast<BYTE>(GetPrivateProfileInt("Pattern Editor", "DefaultSequenceMargins", 2, iniFile)); + gbShowHackControls = (0 != GetPrivateProfileDWord("Misc", "ShowHackControls", 0, iniFile)); GetPrivateProfileString("Paths", "Songs_Directory", m_szModDir, m_szModDir, INIBUFFERSIZE, iniFile); GetPrivateProfileString("Paths", "Samples_Directory", m_szSmpDir, m_szSmpDir, INIBUFFERSIZE, iniFile); Modified: trunk/OpenMPT/mptrack/Mainfrm.h =================================================================== --- trunk/OpenMPT/mptrack/Mainfrm.h 2008-10-13 14:25:58 UTC (rev 227) +++ trunk/OpenMPT/mptrack/Mainfrm.h 2008-10-13 15:19:08 UTC (rev 228) @@ -365,6 +365,7 @@ // Globals static UINT m_nLastOptionsPage, m_nFilterIndex; static BOOL gbMdiMaximize; + static bool gbShowHackControls; static LONG glCtrlWindowHeight, glTreeWindowWidth, glTreeSplitRatio; static LONG glGeneralWindowHeight, glPatternWindowHeight, glSampleWindowHeight, glInstrumentWindowHeight, glCommentsWindowHeight, glGraphWindowHeight; //rewbs.varWindowSize Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2008-10-13 14:25:58 UTC (rev 227) +++ trunk/OpenMPT/mptrack/mptrack.rc 2008-10-13 15:19:08 UTC (rev 228) @@ -675,23 +675,15 @@ BEGIN CONTROL "Toolbar1",IDC_TOOLBAR1,"ToolbarWindow32",WS_GROUP | 0x4d,4,4,55,17 - RTEXT "Sample",IDC_STATIC,62,8,24,8 EDITTEXT IDC_EDIT_SAMPLE,90,6,35,12,ES_AUTOHSCROLL | ES_NUMBER CONTROL "Spin6",IDC_SPIN_SAMPLE,"msctls_updown32",UDS_WRAP | UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,118,4,11,14 COMBOBOX IDC_COMBO_ZOOM,131,6,41,89,CBS_DROPDOWNLIST | WS_VSCROLL - CTEXT "Length: 000000 (16-bit)",IDC_TEXT5,175,6,90,13, - SS_CENTERIMAGE,WS_EX_STATICEDGE - CONTROL "Toolbar2",IDC_TOOLBAR2,"ToolbarWindow32",WS_GROUP | - 0x4d,268,4,136,17 - GROUPBOX "",IDC_STATIC,3,22,94,78 - LTEXT "Default Volume",IDC_STATIC,8,32,49,8 EDITTEXT IDC_EDIT7,57,30,36,12,ES_NUMBER CONTROL "Spin1",IDC_SPIN7,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,87,29, 11,11 - LTEXT "Global Volume",IDC_STATIC,8,45,46,8 EDITTEXT IDC_EDIT8,57,43,36,12,ES_NUMBER CONTROL "Spin1",IDC_SPIN8,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,87,42, @@ -702,79 +694,46 @@ CONTROL "Spin1",IDC_SPIN9,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,87,56, 11,11 - LTEXT "FineTune",IDC_TEXT7,8,73,37,8 EDITTEXT IDC_EDIT5,48,70,45,12,ES_AUTOHSCROLL CONTROL "Spin1",IDC_SPIN5,"msctls_updown32",UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,87,69,11,11 - LTEXT "Transpose",IDC_TEXT6,8,86,38,8 COMBOBOX IDC_COMBO_BASENOTE,48,83,45,89,CBS_DROPDOWNLIST | WS_VSCROLL - CTEXT "Name",IDC_STATIC,102,26,28,12,SS_CENTERIMAGE | NOT - WS_GROUP,WS_EX_STATICEDGE EDITTEXT IDC_SAMPLE_NAME,129,26,135,12,ES_AUTOHSCROLL - CTEXT "File",IDC_STATIC,269,26,23,13,SS_CENTERIMAGE | NOT - WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE EDITTEXT IDC_SAMPLE_FILENAME,292,26,72,13,ES_AUTOHSCROLL - GROUPBOX "Loop",IDC_STATIC,102,43,79,57 - LTEXT "Type",IDC_STATIC,107,57,17,8 COMBOBOX IDC_COMBO1,130,54,45,46,CBS_DROPDOWNLIST | WS_TABSTOP - LTEXT "Start",IDC_STATIC,107,73,16,8 EDITTEXT IDC_EDIT1,130,70,45,12,ES_NUMBER CONTROL "Spin1",IDC_SPIN1,"msctls_updown32",UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,169,69,11,11 - LTEXT "End",IDC_STATIC,107,86,14,8 EDITTEXT IDC_EDIT2,130,83,45,12,ES_NUMBER CONTROL "Spin1",IDC_SPIN2,"msctls_updown32",UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,169,84,11,11 - GROUPBOX "Sustain Loop",IDC_STATIC,185,43,79,57 - LTEXT "Type",IDC_STATIC,189,57,17,8 COMBOBOX IDC_COMBO2,212,54,45,46,CBS_DROPDOWNLIST | WS_TABSTOP - LTEXT "Start",IDC_STATIC,189,73,16,8 EDITTEXT IDC_EDIT3,212,70,45,12,ES_NUMBER CONTROL "Spin1",IDC_SPIN3,"msctls_updown32",UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,253,70,11,11 - LTEXT "End",IDC_STATIC,189,86,14,8 EDITTEXT IDC_EDIT4,212,83,45,12,ES_NUMBER CONTROL "Spin1",IDC_SPIN4,"msctls_updown32",UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,253,83,11,11 - GROUPBOX "",IDC_STATIC,269,43,96,57 COMBOBOX IDC_COMBO3,275,59,47,70,CBS_DROPDOWNLIST | WS_TABSTOP - LTEXT "Depth",IDC_STATIC,327,50,20,8 EDITTEXT IDC_EDIT15,327,59,32,12,ES_NUMBER CONTROL "Depth",IDC_SPIN12,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,353,59, 11,11 - LTEXT "Sweep",IDC_STATIC,275,74,23,8 EDITTEXT IDC_EDIT14,275,83,38,12,ES_NUMBER CONTROL "Sweep",IDC_SPIN11,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,305,84, 11,11 - LTEXT "Rate",IDC_STATIC,321,74,16,8 EDITTEXT IDC_EDIT16,321,83,38,12,ES_NUMBER CONTROL "Rate",IDC_SPIN13,"msctls_updown32",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,353,83, 11,11 - LTEXT "Auto-Vibrato",IDC_STATIC,275,50,41,8 - GROUPBOX "Pitch shifting / Time stretching", - IDC_GROUPBOX_PITCH_TIME,370,22,150,78,NOT WS_VISIBLE - LTEXT "Pitch",IDC_TEXT_PITCH,374,38,23,10,NOT WS_VISIBLE - LTEXT "Quality",IDC_TEXT_QUALITY,374,54,23,10,NOT WS_VISIBLE - LTEXT "FFT",IDC_TEXT_FFT,374,70,23,10,NOT WS_VISIBLE + CONTROL "Time stretching",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | + BS_LEFTTEXT | BS_FLAT | NOT WS_VISIBLE | WS_TABSTOP,446, + 36,68,11 CONTROL "Preview mode",IDC_CHECK2,"Button",BS_AUTOCHECKBOX | BS_LEFTTEXT | BS_FLAT | NOT WS_VISIBLE | WS_TABSTOP,373, 83,65,11 - CONTROL "Time stretching",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | - BS_LEFTTEXT | BS_FLAT | NOT WS_VISIBLE | WS_TABSTOP,446, - 36,68,11 - EDITTEXT IDC_EDIT6,446,51,45,13,ES_RIGHT | ES_AUTOHSCROLL | NOT - WS_VISIBLE,WS_EX_RIGHT - CTEXT "Static",IDC_TEXT_PREVIEW,448,69,67,10,NOT WS_VISIBLE - PUSHBUTTON "Process",IDC_BUTTON1,448,80,67,16,NOT WS_VISIBLE, - WS_EX_CLIENTEDGE - PUSHBUTTON "...",IDC_BUTTON2,502,51,13,13,NOT WS_VISIBLE, - WS_EX_CLIENTEDGE - PUSHBUTTON "Keep",IDC_BUTTON3,448,82,32,13,NOT WS_VISIBLE, - WS_EX_CLIENTEDGE PUSHBUTTON "Restore",IDC_BUTTON4,482,82,33,13,NOT WS_VISIBLE, WS_EX_CLIENTEDGE COMBOBOX IDC_COMBO4,400,35,39,61,CBS_DROPDOWNLIST | NOT @@ -783,7 +742,50 @@ WS_VISIBLE | WS_VSCROLL | WS_GROUP | WS_TABSTOP COMBOBOX IDC_COMBO6,400,67,39,61,CBS_DROPDOWNLIST | NOT WS_VISIBLE | WS_VSCROLL | WS_GROUP | WS_TABSTOP + EDITTEXT IDC_EDIT_STRETCHPARAMS,374,51,64,12,ES_AUTOHSCROLL + EDITTEXT IDC_EDIT6,446,51,45,12,ES_RIGHT | ES_AUTOHSCROLL | NOT + WS_VISIBLE,WS_EX_RIGHT + PUSHBUTTON "...",IDC_BUTTON2,502,51,13,13,NOT WS_VISIBLE, + WS_EX_CLIENTEDGE + RTEXT "Sample",IDC_STATIC,62,8,24,8 + CTEXT "Length: 000000 (16-bit)",IDC_TEXT5,175,6,90,13, + SS_CENTERIMAGE,WS_EX_STATICEDGE + CONTROL "Toolbar2",IDC_TOOLBAR2,"ToolbarWindow32",WS_GROUP | + 0x4d,268,4,136,17 + GROUPBOX "",IDC_STATIC,3,22,94,78 + LTEXT "Default Volume",IDC_STATIC,8,32,49,8 + LTEXT "Global Volume",IDC_STATIC,8,45,46,8 + LTEXT "FineTune",IDC_TEXT7,8,73,37,8 + LTEXT "Transpose",IDC_TEXT6,8,86,38,8 + CTEXT "Name",IDC_STATIC,102,26,28,12,SS_CENTERIMAGE | NOT + WS_GROUP,WS_EX_STATICEDGE + CTEXT "File",IDC_STATIC,269,26,23,13,SS_CENTERIMAGE | NOT + WS_GROUP | WS_TABSTOP,WS_EX_STATICEDGE + GROUPBOX "Loop",IDC_STATIC,102,43,79,57 + LTEXT "Type",IDC_STATIC,107,57,17,8 + LTEXT "Start",IDC_STATIC,107,73,16,8 + LTEXT "End",IDC_STATIC,107,86,14,8 + GROUPBOX "Sustain Loop",IDC_STATIC,185,43,79,57 + LTEXT "Type",IDC_STATIC,189,57,17,8 + LTEXT "Start",IDC_STATIC,189,73,16,8 + LTEXT "End",IDC_STATIC,189,86,14,8 + GROUPBOX "",IDC_STATIC,269,43,96,57 + LTEXT "Auto-Vibrato",IDC_STATIC,275,50,41,8 + LTEXT "Sweep",IDC_STATIC,275,74,23,8 + LTEXT "Depth",IDC_STATIC,327,50,20,8 + LTEXT "Rate",IDC_STATIC,321,74,16,8 + GROUPBOX "Pitch shifting / Time stretching", + IDC_GROUPBOX_PITCH_TIME,370,22,150,78,NOT WS_VISIBLE + PUSHBUTTON "Process",IDC_BUTTON1,448,80,67,16,NOT WS_VISIBLE, + WS_EX_CLIENTEDGE + LTEXT "Pitch",IDC_TEXT_PITCH,373,36,23,10,NOT WS_VISIBLE + LTEXT "Quality",IDC_TEXT_QUALITY,374,54,23,10,NOT WS_VISIBLE + LTEXT "FFT",IDC_TEXT_FFT,374,68,23,10,NOT WS_VISIBLE + CTEXT "Static",IDC_TEXT_PREVIEW,448,69,67,10,NOT WS_VISIBLE + PUSHBUTTON "Keep",IDC_BUTTON3,448,82,32,13,NOT WS_VISIBLE, + WS_EX_CLIENTEDGE LTEXT "%",IDC_TEXT_PERCENT,494,53,8,10,NOT WS_VISIBLE + LTEXT "Parameters",IDC_TEXT_STRETCHPARAMS,385,38,39,8 END IDD_CONTROL_INSTRUMENTS DIALOGEX 0, 0, 558, 173 Modified: trunk/OpenMPT/mptrack/mptrack.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack.vcproj 2008-10-13 14:25:58 UTC (rev 227) +++ trunk/OpenMPT/mptrack/mptrack.vcproj 2008-10-13 15:19:08 UTC (rev 228) @@ -24,7 +24,7 @@ AdditionalOptions="/EHsc" Optimization="0" OptimizeForProcessor="1" - AdditionalIncludeDirectories="..\unlha,..\unzip,..\unrar,..\soundlib,..\include,..\xsoundlib" + AdditionalIncludeDirectories="..\unlha,..\unzip,..\unrar,..\soundlib,..\include,..\xsoundlib,..\" PreprocessorDefinitions="_DEBUG,WIN32,_WINDOWS,ENABLE_EQ,MODPLUG_TRACKER,NO_PACKING,HAVE_DOT_NET,ENABLE_AMD,ENABLE_SSE,ENABLE_AMDNOW,ENABLE_MMX" StringPooling="TRUE" BasicRuntimeChecks="3" @@ -48,13 +48,13 @@ <Tool Name="VCLinkerTool" AdditionalOptions="/MACHINE:I386" - AdditionalDependencies="winmm.lib strmiids.lib dmoguids.lib version.lib opengl32.lib glu32.lib Rpcrt4.lib" + AdditionalDependencies="winmm.lib strmiids.lib dmoguids.lib version.lib opengl32.lib glu32.lib Rpcrt4.lib delayimp.lib" OutputFile=".\Debug/mptrack.exe" Version="5.0" LinkIncremental="2" SuppressStartupBanner="TRUE" AdditionalLibraryDirectories="" - DelayLoadDLLs="" + DelayLoadDLLs="OpenMPT_soundtouch.dll" GenerateDebugInformation="TRUE" AssemblyDebug="1" ProgramDatabaseFile=".\Debug/mptrack.pdb" @@ -104,7 +104,7 @@ GlobalOptimizations="TRUE" InlineFunctionExpansion="2" OptimizeForWindowsApplication="TRUE" - AdditionalIncludeDirectories="..\unlha,..\unzip,..\unrar,..\soundlib,..\include,..\xsoundlib" + AdditionalIncludeDirectories="..\unlha,..\unzip,..\unrar,..\soundlib,..\include,..\xsoundlib,..\" PreprocessorDefinitions="NDEBUG,WIN32,_WINDOWS,ENABLE_MMX,ENABLE_EQ,MODPLUG_TRACKER,NO_PACKING,HAVE_DOT_NET,ENABLE_AMD,ENABLE_SSE,ENABLE_AMDNOW" StringPooling="TRUE" RuntimeLibrary="0" @@ -119,21 +119,26 @@ ProgramDataBaseFileName=".\Release/" WarningLevel="3" SuppressStartupBanner="FALSE" + DebugInformationFormat="3" CompileAs="0"/> <Tool Name="VCCustomBuildTool"/> <Tool Name="VCLinkerTool" AdditionalOptions="/MACHINE:I386" - AdditionalDependencies="winmm.lib strmiids.lib dmoguids.lib version.lib opengl32.lib glu32.lib Rpcrt4.lib" + AdditionalDependencies="winmm.lib strmiids.lib dmoguids.lib version.lib opengl32.lib glu32.lib Rpcrt4.lib delayimp.lib" OutputFile=".\Bin/mptrack.exe" Version="5.0" LinkIncremental="1" SuppressStartupBanner="TRUE" AdditionalLibraryDirectories="" + DelayLoadDLLs="OpenMPT_soundtouch.dll" + GenerateDebugInformation="TRUE" GenerateMapFile="FALSE" MapFileName=".\Release/mptrack.map" - SubSystem="2"/> + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2"/> <Tool Name="VCMIDLTool" PreprocessorDefinitions="NDEBUG" Modified: trunk/OpenMPT/mptrack/res/MPTRACK.RC2 =================================================================== --- trunk/OpenMPT/mptrack/res/MPTRACK.RC2 2008-10-13 14:25:58 UTC (rev 227) +++ trunk/OpenMPT/mptrack/res/MPTRACK.RC2 2008-10-13 15:19:08 UTC (rev 228) @@ -43,7 +43,7 @@ VALUE "FileDescription", "OpenMPT / ModPlug Tracker" VALUE "FileVersion", VER_FILEVERSION_STR VALUE "InternalName", "Modplug Tracker" - VALUE "LegalCopyright", "Copyright \xA91997-2003 Olivier Lapicque; \xA92004-2007 GPL." + VALUE "LegalCopyright", "Copyright \xA91997-2003 Olivier Lapicque; \xA92004-2008 contributors." VALUE "LegalTrademarks", "M.O.D.P.L.U.G" VALUE "OriginalFilename", "mptrack.exe" VALUE "PrivateBuild", "" Modified: trunk/OpenMPT/mptrack/resource.h =================================================================== --- trunk/OpenMPT/mptrack/resource.h 2008-10-13 14:25:58 UTC (rev 227) +++ trunk/OpenMPT/mptrack/resource.h 2008-10-13 15:19:08 UTC (rev 228) @@ -818,6 +818,8 @@ #define IDC_TEXT_QUALITY 2330 #define IDC_TEXT_FFT 2331 #define IDC_TEXT_PERCENT 2332 +#define IDC_TEXT_STRETCHPARAMS 2337 +#define IDC_EDIT_STRETCHPARAMS 2338 #define ID_FILE_NEWMOD 32771 #define ID_FILE_NEWXM 32772 #define ID_FILE_NEWS3M 32773 @@ -1049,7 +1051,7 @@ #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 516 #define _APS_NEXT_COMMAND_VALUE 59212 -#define _APS_NEXT_CONTROL_VALUE 2333 +#define _APS_NEXT_CONTROL_VALUE 2339 #define _APS_NEXT_SYMED_VALUE 901 #endif #endif Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2008-10-13 14:25:58 UTC (rev 227) +++ trunk/OpenMPT/soundlib/Sndfile.h 2008-10-13 15:19:08 UTC (rev 228) @@ -427,14 +427,18 @@ BYTE nVibRate; CHAR name[22]; - //Should return the size which pSample is at least. - DWORD GetSampleSizeInBytes() const - { - DWORD len = nLength; - if(uFlags & CHN_16BIT) len *= 2; - if(uFlags & CHN_STEREO) len *= 2; - return len; - } + // Return the size of one (elementary) sample in bytes. + uint8 GetElementarySampleSize() const {return (uFlags & CHN_16BIT) ? 2 : 1;} + + // Return the number of channels in the sample. + uint8 GetNumChannels() const {return (uFlags & CHN_STEREO) ? 2 : 1;} + + // Return the size which pSample is at least. + DWORD GetSampleSizeInBytes() const {return nLength * GetNumChannels() * GetElementarySampleSize();} + + // Returns sample rate of the sample. The argument is needed because + // the sample rate is obtained differently for different module types. + uint32 GetSampleRate(const MODTYPE type) const; }; @@ -1293,7 +1297,18 @@ long GetSampleOffset(); }; +inline uint32 MODINSTRUMENT::GetSampleRate(const MODTYPE type) const +//------------------------------------------------------------------ +{ + uint32 nRate; + if(type & (MOD_TYPE_MOD|MOD_TYPE_XM)) + nRate = CSoundFile::TransposeToFrequency(RelativeTone, nFineTune); + else + nRate = nC4Speed; + return (nRate > 0) ? nRate : 8363; +} + inline IMixPlugin* CSoundFile::GetInstrumentPlugin(INSTRUMENTINDEX instr) //---------------------------------------------------------------- { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2008-10-18 21:21:33
|
Revision: 232 http://modplug.svn.sourceforge.net/modplug/?rev=232&view=rev Author: relabsoluness Date: 2008-10-18 21:21:29 +0000 (Sat, 18 Oct 2008) Log Message: ----------- (Patches from Jojo, merged with some fixes) + In sample view: Status bar now displays offset value at given sample point. . Small fixes to sample trimming usability. Modified Paths: -------------- trunk/OpenMPT/mptrack/View_smp.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/mptrack/View_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_smp.cpp 2008-10-18 12:35:46 UTC (rev 231) +++ trunk/OpenMPT/mptrack/View_smp.cpp 2008-10-18 21:21:29 UTC (rev 232) @@ -20,6 +20,12 @@ #define MIN_ZOOM 0 #define MAX_ZOOM 8 +// Defines the minimum length for selection for which +// trimming will be done. This is the minimum value for +// selection difference, so the minimum length of result +// of trimming is nTrimLengthMin + 1. +const uint8 nTrimLengthMin = 16; + const UINT cLeftBarButtons[SMP_LEFTBAR_BUTTONS] = { ID_SAMPLE_ZOOMUP, @@ -1176,9 +1182,32 @@ pSndFile = pModDoc->GetSoundFile(); if (m_rcClient.PtInRect(point)) { - LONG x = ScreenToSample(point.x); - wsprintf(s, "Cursor: %d", x); + const DWORD x = ScreenToSample(point.x); + wsprintf(s, "Cursor: %u", x); UpdateIndicator(s); + CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); + + if (pMainFrm && m_dwEndSel <= m_dwBeginSel) + { + if(m_nSample > 0 && m_nSample < MAX_SAMPLES && x < pSndFile->Ins[m_nSample].nLength ) + { + const DWORD xLow = (x / 0x100) % 0x100; + const DWORD xHigh = x / 0x10000; + const char cOffsetChar = (pSndFile->TypeIsS3M_IT_MPT()) ? gszS3mCommands[CMD_OFFSET] : gszModCommands[CMD_OFFSET]; + const bool bHasHighOffset = (pSndFile->TypeIsS3M_IT_MPT() || (pSndFile->GetType() == MOD_TYPE_XM)); + const char cHighOffsetChar = (pSndFile->TypeIsS3M_IT_MPT()) ? gszS3mCommands[CMD_S3MCMDEX] : gszModCommands[CMD_XFINEPORTAUPDOWN]; + + if(xHigh == 0) + wsprintf(s, "Offset: %c%02X", cOffsetChar, xLow); + else if(bHasHighOffset && xHigh < 0x10) + wsprintf(s, "Offset: %c%02X, %cA%X", cOffsetChar, xLow, cHighOffsetChar, xHigh); + else + wsprintf(s, "Beyond offset range"); + pMainFrm->SetInfoText(s); + } + else + pMainFrm->SetInfoText(""); + } } else UpdateIndicator(NULL); if (m_dwStatus & SMPSTATUS_MOUSEDRAG) { @@ -1332,13 +1361,19 @@ // "Trim" menu item is responding differently if there's no selection, // but a loop present: "trim around loop point"! (jojo in topic 2258) std::string sTrimMenuText = "Trim"; - bool bIsGrayed = (m_dwEndSel<=m_dwBeginSel); + bool bIsGrayed = ( (m_dwEndSel<=m_dwBeginSel) || (m_dwEndSel - m_dwBeginSel < nTrimLengthMin) + || (m_dwEndSel - m_dwBeginSel == pins->nLength) + ); if ((m_dwBeginSel == m_dwEndSel) && (pins->nLoopStart < pins->nLoopEnd)) { // no selection => use loop points sTrimMenuText += " around loop points"; - bIsGrayed = false; + // Check whether trim menu item can be enabled (loop not too short or long for trimming). + if( (pins->nLoopEnd <= pins->nLength) && + (pins->nLoopEnd - pins->nLoopStart >= nTrimLengthMin) && + (pins->nLoopEnd - pins->nLoopStart < pins->nLength) ) + bIsGrayed = false; } sTrimMenuText += "\t" + ih->GetKeyTextFromCommand(kcSampleTrim); @@ -1862,7 +1897,7 @@ UINT nStart = m_dwBeginSel; UINT nEnd = m_dwEndSel - m_dwBeginSel; - if ((pins->pSample) && (nStart+nEnd <= pins->nLength) && (nEnd >= 16)) + if ((pins->pSample) && (nStart+nEnd <= pins->nLength) && (nEnd >= nTrimLengthMin)) { BEGIN_CRITICAL(); { Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2008-10-18 12:35:46 UTC (rev 231) +++ trunk/OpenMPT/soundlib/Sndfile.h 2008-10-18 21:21:29 UTC (rev 232) @@ -973,6 +973,8 @@ BOOL Destroy(); MODTYPE GetType() const { return m_nType; } inline bool TypeIsIT_MPT() const {return (m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT)) != 0;} + inline bool TypeIsS3M_IT_MPT() const {return (m_nType & (MOD_TYPE_S3M | MOD_TYPE_IT | MOD_TYPE_MPT)) != 0;} + inline bool TypeIsXM_MOD() const {return (m_nType & (MOD_TYPE_XM | MOD_TYPE_MOD)) != 0;} CModDoc* GetpModDoc() {return m_pModDoc;} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2008-10-24 18:33:21
|
Revision: 233 http://modplug.svn.sourceforge.net/modplug/?rev=233&view=rev Author: relabsoluness Date: 2008-10-24 18:33:16 +0000 (Fri, 24 Oct 2008) Log Message: ----------- . When loading S3M files which contain Zxx-effects, user is now asked how to process them. (bug 2166) Modified Paths: -------------- trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/soundlib/Load_s3m.cpp Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2008-10-18 21:21:29 UTC (rev 232) +++ trunk/OpenMPT/mptrack/Moddoc.h 2008-10-24 18:33:16 UTC (rev 233) @@ -143,6 +143,7 @@ CSoundFile *GetSoundFile() { return &m_SndFile; } void SetPause(BOOL bPause) { m_bPaused = bPause; } void SetModified(BOOL bModified=TRUE) { SetModifiedFlag(bModified); } + void SetShowSaveDialog(bool b) {m_ShowSavedialog = b;} void PostMessageToAllViews(UINT uMsg, WPARAM wParam=0, LPARAM lParam=0); void SendMessageToActiveViews(UINT uMsg, WPARAM wParam=0, LPARAM lParam=0); UINT GetModType() const { return m_SndFile.m_nType; } Modified: trunk/OpenMPT/soundlib/Load_s3m.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_s3m.cpp 2008-10-18 21:21:29 UTC (rev 232) +++ trunk/OpenMPT/soundlib/Load_s3m.cpp 2008-10-24 18:33:16 UTC (rev 233) @@ -10,11 +10,49 @@ #include "stdafx.h" #include "sndfile.h" +#include "../mptrack/moddoc.h" #pragma warning(disable:4244) //"conversion from 'type1' to 'type2', possible loss of data" extern WORD S3MFineTuneTable[16]; +static void HandleZxx(uint8& nType, MODCOMMAND* const m) +//------------------------------------------------------------------- +{ + if(nType == 0) + { + CString str; + str.Format(GetStrI18N("The S3M file contains Zxx effect. " + "It can be processed in the following ways:\n" + "Yes : Convert Zxx to S8x(set panning)-effects (PixPlay)\n" + "No : Remove Zxx effects\n" + "Cancel: Keep Zxx effects\n" + "\nNote that options (yes) and (no) modify the loaded pattern data." + )); + const int nResult = ::AfxMessageBox(str, MB_YESNOCANCEL|MB_ICONINFORMATION); + + if(nResult == IDYES) + nType = 2; + else if(nResult == IDNO) + nType = 3; + else + nType = 1; + } + if(nType != 1) + { + if(nType == 2) + { + m->command = CMD_S3MCMDEX; + m->param = 0x80 + (m->param & 0xF); + } + else + { + m->command = 0; + m->param = 0; + } + } +} + ////////////////////////////////////////////////////// // ScreamTracker S3M file support @@ -335,6 +373,7 @@ } } // Reading patterns + uint8 nZxxHandling = 0; for (UINT iPat=0; iPat<patnum; iPat++) { UINT nInd = ((DWORD)ptr[nins+iPat]) << 4; @@ -387,6 +426,10 @@ m->command = src[j++]; m->param = src[j++]; if (m->command) S3MConvert(m, FALSE); + if(m->command == CMD_MIDI) + { + HandleZxx(nZxxHandling, m); + } } } else { @@ -411,6 +454,12 @@ m_nMinPeriod = 64; m_nMaxPeriod = 32767; if (psfh.flags & 0x10) m_dwSongFlags |= SONG_AMIGALIMITS; + + if(nZxxHandling != 0 && nZxxHandling != 1 && GetpModDoc() != 0) + { + GetpModDoc()->SetModified(); + GetpModDoc()->SetShowSaveDialog(true); + } return TRUE; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2008-12-07 23:59:18
|
Revision: 236 http://modplug.svn.sourceforge.net/modplug/?rev=236&view=rev Author: relabsoluness Date: 2008-12-07 23:59:12 +0000 (Sun, 07 Dec 2008) Log Message: ----------- (Patches from Jojo, merged slightly modified) / Instrument tab: Sample map can now map "No sample". + Sample tab: Ability to save sample as raw. / Setup: Updated directory browsing dialogs. . Misc: When adding channels from song properties, initialize new channels properly (bug 1814). Modified Paths: -------------- trunk/OpenMPT/mptrack/AutoSaver.cpp trunk/OpenMPT/mptrack/Ctrl_smp.cpp trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/Moptions.cpp trunk/OpenMPT/mptrack/dlg_misc.cpp trunk/OpenMPT/soundlib/Sampleio.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/mptrack/AutoSaver.cpp =================================================================== --- trunk/OpenMPT/mptrack/AutoSaver.cpp 2008-11-03 21:30:18 UTC (rev 235) +++ trunk/OpenMPT/mptrack/AutoSaver.cpp 2008-12-07 23:59:12 UTC (rev 236) @@ -378,8 +378,9 @@ GetDlgItemText(IDC_AUTOSAVE_PATH, szPath, sizeof(szPath)); memset(&bi, 0, sizeof(bi)); bi.hwndOwner = m_hWnd; + bi.lpszTitle = "Select a folder to store autosaved files in..."; bi.pszDisplayName = szPath; - bi.ulFlags = BIF_RETURNONLYFSDIRS; + bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI; LPITEMIDLIST pid = SHBrowseForFolder(&bi); if (pid != NULL) { @@ -442,4 +443,4 @@ } return CPropertyPage::OnKillActive(); -} \ No newline at end of file +} Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2008-11-03 21:30:18 UTC (rev 235) +++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2008-12-07 23:59:12 UTC (rev 236) @@ -959,7 +959,7 @@ void CCtrlSamples::OnSampleSave() //------------------------------- { - CHAR szFileName[_MAX_PATH] = ""; + CHAR szFileName[_MAX_PATH] = "", ext[_MAX_EXT]; if ((!m_pSndFile) || (!m_nSample) || (!m_pSndFile->Ins[m_nSample].pSample)) { @@ -979,7 +979,8 @@ CFileDialog dlg(FALSE, "wav", szFileName, OFN_HIDEREADONLY| OFN_ENABLESIZING | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST | OFN_NOREADONLYRETURN, - "Wave File (*.wav)|*.wav||", + "Wave File (*.wav)|*.wav|" + "RAW Audio (*.raw)|*.raw||", this); if (CMainFrame::m_szCurSmpDir[0]) { @@ -987,7 +988,13 @@ } if (dlg.DoModal() != IDOK) return; BeginWaitCursor(); - BOOL bOk = m_pSndFile->SaveWAVSample(m_nSample, dlg.GetPathName()); + + _splitpath(dlg.GetPathName(), NULL, NULL, NULL, ext); + BOOL bOk = FALSE; + if (!lstrcmpi(ext, ".raw")) + bOk = m_pSndFile->SaveRAWSample(m_nSample, dlg.GetPathName()); + else + bOk = m_pSndFile->SaveWAVSample(m_nSample, dlg.GetPathName()); EndWaitCursor(); if (!bOk) { Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2008-11-03 21:30:18 UTC (rev 235) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2008-12-07 23:59:12 UTC (rev 236) @@ -409,6 +409,13 @@ m_SndFile.Patterns[i] = newp; CSoundFile::FreePattern(p); } + + //if channel was removed before and is added again, mute status has to be unset! (bug 1814) + for (UINT i=m_SndFile.m_nChannels; i<nNewChannels; i++) + { + m_SndFile.InitChannel(i); + } + m_SndFile.m_nChannels = nNewChannels; END_CRITICAL(); EndWaitCursor(); Modified: trunk/OpenMPT/mptrack/Moptions.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moptions.cpp 2008-11-03 21:30:18 UTC (rev 235) +++ trunk/OpenMPT/mptrack/Moptions.cpp 2008-12-07 23:59:12 UTC (rev 236) @@ -786,8 +786,9 @@ GetDlgItemText(nID, szPath, sizeof(szPath)); memset(&bi, 0, sizeof(bi)); bi.hwndOwner = m_hWnd; + bi.lpszTitle = "Select a default folder..."; bi.pszDisplayName = szPath; - bi.ulFlags = BIF_RETURNONLYFSDIRS; + bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI; LPITEMIDLIST pid = SHBrowseForFolder(&bi); if (pid != NULL) { Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp =================================================================== --- trunk/OpenMPT/mptrack/dlg_misc.cpp 2008-11-03 21:30:18 UTC (rev 235) +++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2008-12-07 23:59:12 UTC (rev 236) @@ -2571,6 +2571,11 @@ } m_CbnSample.ResetContent(); bAll = IsDlgButtonChecked(IDC_CHECK1); + + UINT nInsertPos; + nInsertPos = m_CbnSample.AddString("0: No sample"); + m_CbnSample.SetItemData(nInsertPos, 0); + for (UINT i=1; i<=m_pSndFile->m_nSamples; i++) { BOOL bUsed = bAll; @@ -2585,10 +2590,10 @@ if (bUsed) { CString sampleName; sampleName.Format("%d: %s", i, m_pSndFile->GetSampleName(i)); - UINT nPos = m_CbnSample.AddString(sampleName); + nInsertPos = m_CbnSample.AddString(sampleName); - m_CbnSample.SetItemData(nPos, i); - if (i == nOldPos) nNewPos = nPos; + m_CbnSample.SetItemData(nInsertPos, i); + if (i == nOldPos) nNewPos = nInsertPos; } } m_CbnSample.SetCurSel(nNewPos); @@ -2647,7 +2652,7 @@ wsprintf(s, "%s", temp.c_str()); INSTRUMENTHEADER *penv = m_pSndFile->Headers[m_nInstrument]; - if ((wParam == KBDNOTIFY_LBUTTONDOWN) && (nSample > 0) && (nSample < MAX_SAMPLES) && (penv)) + if ((wParam == KBDNOTIFY_LBUTTONDOWN) && (nSample < MAX_SAMPLES) && (penv)) { UINT iNote = nBaseOctave*12+lParam; if (KeyboardMap[iNote] == nSample) Modified: trunk/OpenMPT/soundlib/Sampleio.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sampleio.cpp 2008-11-03 21:30:18 UTC (rev 235) +++ trunk/OpenMPT/soundlib/Sampleio.cpp 2008-12-07 23:59:12 UTC (rev 236) @@ -682,6 +682,27 @@ return TRUE; } +/////////////////////////////////////////////////////////////// +// Save RAW + +BOOL CSoundFile::SaveRAWSample(UINT nSample, LPCSTR lpszFileName) +//--------------------------------------------------------------- +{ + MODINSTRUMENT *pins = &Ins[nSample]; + FILE *f; + + if ((f = fopen(lpszFileName, "wb")) == NULL) return FALSE; + + UINT nType; + if (pins->uFlags & CHN_STEREO) + nType = (pins->uFlags & CHN_16BIT) ? RS_STIPCM16S : RS_STIPCM8S; + else + nType = (pins->uFlags & CHN_16BIT) ? RS_PCM16S : RS_PCM8S; + WriteSample(f, pins, nType); + fclose(f); + return TRUE; +} + ///////////////////////////////////////////////////////////// // GUS Patches Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2008-11-03 21:30:18 UTC (rev 235) +++ trunk/OpenMPT/soundlib/Sndfile.h 2008-12-07 23:59:12 UTC (rev 236) @@ -1239,6 +1239,7 @@ BOOL ReadITISample(UINT nSample, LPBYTE lpMemFile, DWORD dwFileLength); BOOL Read8SVXSample(UINT nInstr, LPBYTE lpMemFile, DWORD dwFileLength); BOOL SaveWAVSample(UINT nSample, LPCSTR lpszFileName); + BOOL SaveRAWSample(UINT nSample, LPCSTR lpszFileName); // Instrument file I/O BOOL ReadInstrumentFromFile(UINT nInstr, LPBYTE lpMemFile, DWORD dwFileLength); BOOL ReadXIInstrument(UINT nInstr, LPBYTE lpMemFile, DWORD dwFileLength); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2008-12-11 01:59:51
|
Revision: 237 http://modplug.svn.sourceforge.net/modplug/?rev=237&view=rev Author: relabsoluness Date: 2008-12-11 01:33:04 +0000 (Thu, 11 Dec 2008) Log Message: ----------- (Patches from Jojo, merged somewhat modified) / Setup: Added notification about equalizer. / Sequence view: Sequence scrolling won't no longer be cut on first '---' item on IT/MPTM/XM. Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_seq.cpp trunk/OpenMPT/mptrack/Mpdlgs.cpp trunk/OpenMPT/mptrack/OrderToPatternTable.cpp trunk/OpenMPT/mptrack/OrderToPatternTable.h trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/mptrack/Ctrl_seq.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2008-12-07 23:59:12 UTC (rev 236) +++ trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2008-12-11 01:33:04 UTC (rev 237) @@ -114,10 +114,17 @@ CSoundFile *pSndFile = m_pModDoc->GetSoundFile(); SCROLLINFO info; UINT nPage; - int nMax=0; - const int nSeqLength = pSndFile->Order.size(); - while ((nMax < nSeqLength) && (pSndFile->Order[nMax] != pSndFile->Order.GetInvalidPatIndex())) nMax++; + int nMax = 0; + if(pSndFile->TypeIsIT_MPT_XM()) + { // For IT/MPT/XM, show sequence until the last used item... + nMax = pSndFile->Order.GetLengthTailTrimmed(); + } + else + { // ...and for MOD/S3M, cut shown sequence to first '---' item. + nMax = pSndFile->Order.GetLengthFirstEmpty(); + } + GetScrollInfo(SB_HORZ, &info, SIF_PAGE|SIF_RANGE); info.fMask = SIF_PAGE|SIF_RANGE; info.nMin = 0; Modified: trunk/OpenMPT/mptrack/Mpdlgs.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mpdlgs.cpp 2008-12-07 23:59:12 UTC (rev 236) +++ trunk/OpenMPT/mptrack/Mpdlgs.cpp 2008-12-11 01:33:04 UTC (rev 237) @@ -1033,6 +1033,13 @@ //----------------------------- { CMainFrame::m_nLastOptionsPage = OPTIONS_PAGE_EQ; + SetDlgItemText(IDC_EQ_WARNING, + "Note: This EQ, when enabled from Player tab, is applied to " + "any and all of the modules " + "that you load in OpenMPT; its settings are stored globally, " + "rather than in each file. This means that you should avoid " + "using it as part of your production process, and instead only " + "use it to correct deficiencies in your audio hardware."); return CPropertyPage::OnSetActive(); } Modified: trunk/OpenMPT/mptrack/OrderToPatternTable.cpp =================================================================== --- trunk/OpenMPT/mptrack/OrderToPatternTable.cpp 2008-12-07 23:59:12 UTC (rev 236) +++ trunk/OpenMPT/mptrack/OrderToPatternTable.cpp 2008-12-11 01:33:04 UTC (rev 237) @@ -108,6 +108,29 @@ } +ORDERINDEX COrderToPatternTable::GetLengthTailTrimmed() const +//----------------------------------------------------------- +{ + ORDERINDEX nEnd = GetCount(); + if(nEnd == 0) return 0; + nEnd--; + const PATTERNINDEX iInvalid = GetInvalidPatIndex(); + while(nEnd > 0 && (*this)[nEnd] == iInvalid) + nEnd--; + return ((*this)[nEnd] == iInvalid) ? 0 : nEnd+1; +} + + +ORDERINDEX COrderToPatternTable::GetLengthFirstEmpty() const +//---------------------------------------------------------- +{ + const ORDERINDEX nLength = GetCount(); + ORDERINDEX nMax = 0; + while ((nMax < nLength) && ((*this)[nMax] != (*this).GetInvalidPatIndex())) nMax++; + return nMax; +} + + ORDERINDEX COrderToPatternTable::GetNextOrderIgnoringSkips(const ORDERINDEX start) const //------------------------------------------------------------------------------------- { Modified: trunk/OpenMPT/mptrack/OrderToPatternTable.h =================================================================== --- trunk/OpenMPT/mptrack/OrderToPatternTable.h 2008-12-07 23:59:12 UTC (rev 236) +++ trunk/OpenMPT/mptrack/OrderToPatternTable.h 2008-12-11 01:33:04 UTC (rev 237) @@ -44,6 +44,12 @@ void OnModTypeChanged(const MODTYPE oldtype); + // Returns length of sequence without counting trailing '---' items. + ORDERINDEX GetLengthTailTrimmed() const; + + // Returns length of sequence stopping counting on first '---' (or at the end of sequence). + ORDERINDEX GetLengthFirstEmpty() const; + PATTERNINDEX GetInvalidPatIndex() const; //To correspond 0xFF static PATTERNINDEX GetInvalidPatIndex(const MODTYPE type); Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2008-12-07 23:59:12 UTC (rev 236) +++ trunk/OpenMPT/mptrack/mptrack.rc 2008-12-11 01:33:04 UTC (rev 237) @@ -1324,7 +1324,7 @@ WS_TABSTOP,11,49,88,10 END -IDD_SETUP_EQ DIALOG 0, 0, 240, 156 +IDD_SETUP_EQ DIALOG 0, 0, 240, 202 STYLE DS_SETFONT | WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Equalizer" FONT 8, "MS Sans Serif" @@ -1365,6 +1365,7 @@ PUSHBUTTON "Save Preset...",IDC_BUTTON13,155,124,64,12 CTEXT "Right-click on a band to change its center frequency", IDC_STATIC,20,140,200,8 + LTEXT "EQ Warning Message",IDC_EQ_WARNING,6,157,228,41 END IDD_OPTIONS_AUTHOR DIALOG 0, 0, 240, 150 Modified: trunk/OpenMPT/mptrack/resource.h =================================================================== --- trunk/OpenMPT/mptrack/resource.h 2008-12-07 23:59:12 UTC (rev 236) +++ trunk/OpenMPT/mptrack/resource.h 2008-12-11 01:33:04 UTC (rev 237) @@ -820,6 +820,7 @@ #define IDC_TEXT_QUALITY 2330 #define IDC_TEXT_FFT 2331 #define IDC_TEXT_PERCENT 2332 +#define IDC_EQ_WARNING 2333 #define IDC_TEXT_STRETCHPARAMS 2337 #define IDC_EDIT_STRETCHPARAMS 2338 #define ID_FILE_NEWMOD 32771 Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2008-12-07 23:59:12 UTC (rev 236) +++ trunk/OpenMPT/soundlib/Sndfile.h 2008-12-11 01:33:04 UTC (rev 237) @@ -973,8 +973,10 @@ BOOL Destroy(); MODTYPE GetType() const { return m_nType; } inline bool TypeIsIT_MPT() const {return (m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT)) != 0;} + inline bool TypeIsIT_MPT_XM() const {return (m_nType & (MOD_TYPE_IT | MOD_TYPE_MPT | MOD_TYPE_XM)) != 0;} inline bool TypeIsS3M_IT_MPT() const {return (m_nType & (MOD_TYPE_S3M | MOD_TYPE_IT | MOD_TYPE_MPT)) != 0;} inline bool TypeIsXM_MOD() const {return (m_nType & (MOD_TYPE_XM | MOD_TYPE_MOD)) != 0;} + inline bool TypeIsMOD_S3M() const {return (m_nType & (MOD_TYPE_MOD | MOD_TYPE_S3M)) != 0;} CModDoc* GetpModDoc() {return m_pModDoc;} This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2008-12-11 19:53:08
|
Revision: 238 http://modplug.svn.sourceforge.net/modplug/?rev=238&view=rev Author: relabsoluness Date: 2008-12-11 19:53:02 +0000 (Thu, 11 Dec 2008) Log Message: ----------- / Changed default instrument plug volume command handling from Dry/Wet to none. Also added ini-setting with which one can set the default value used for new instruments. / Added notifications when trying to load unsupported number of patterns or sequence items in mptm. . Tuning collection didn't get marked modified when a tuning was moved to it. . Loading certain old tuning objects didn't work. / Sample tab: Increased possible size of time stretched sample because it may longer than what stretch ratio would suggest. / Sample tab: Time stretch parameter edit is now visible. Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_smp.cpp trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/OrderToPatternTable.cpp trunk/OpenMPT/mptrack/TuningDialog.cpp trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/soundlib/tuning.cpp Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2008-12-11 01:33:04 UTC (rev 237) +++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2008-12-11 19:53:02 UTC (rev 238) @@ -1482,11 +1482,11 @@ GetDlgItem(IDC_COMBO6)->ShowWindow(SW_HIDE); GetDlgItem(IDC_TEXT_PITCH)->ShowWindow(SW_HIDE); GetDlgItem(IDC_COMBO4)->ShowWindow(SW_HIDE); - if(CMainFrame::gbShowHackControls == true) - { + //if(CMainFrame::gbShowHackControls == true) + //{ GetDlgItem(IDC_TEXT_STRETCHPARAMS)->ShowWindow(SW_SHOW); GetDlgItem(IDC_EDIT_STRETCHPARAMS)->ShowWindow(SW_SHOW); - } + //} SetDlgItemText(IDC_BUTTON1, "Time Stretch"); UpdateTimeStretchParameterString(); } @@ -1768,8 +1768,10 @@ const BYTE smpsize = pins->GetElementarySampleSize(); const UINT nChn = pins->GetNumChannels(); - // Allocate new sample - const DWORD nNewSampleLength = (DWORD)(0.5 + ratio * (double)pins->nLength); + // Allocate new sample. Returned sample may not be exactly the size what ratio would suggest + // so allocate a bit more(1.03*). + const DWORD nNewSampleLength = (DWORD)(1.03 * ratio * (double)pins->nLength); + //const DWORD nNewSampleLength = (DWORD)(0.5 + ratio * (double)pins->nLength); PVOID pSample = pins->pSample; PVOID pNewSample = CSoundFile::AllocateSample(nNewSampleLength * nChn * smpsize); if(pNewSample == NULL) @@ -1851,7 +1853,7 @@ while(pos < pins->nLength) { // Current chunk size limit test - if(pos + len >= pins->nLength) len = pins->nLength - pos; + if(len >= pins->nLength - pos) len = pins->nLength - pos; // Show progress bar using process button painting & text label CHAR progress[16]; Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2008-12-11 01:33:04 UTC (rev 237) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2008-12-11 19:53:02 UTC (rev 238) @@ -430,6 +430,8 @@ gnAutoChordWaitTime = GetPrivateProfileDWord("Pattern Editor", "AutoChordWaitTime", 60, iniFile); COrderList::s_nDefaultMargins = static_cast<BYTE>(GetPrivateProfileInt("Pattern Editor", "DefaultSequenceMargins", 2, iniFile)); gbShowHackControls = (0 != GetPrivateProfileDWord("Misc", "ShowHackControls", 0, iniFile)); + CSoundFile::s_DefaultPlugVolumeHandling = static_cast<uint8>(GetPrivateProfileInt("Misc", "DefaultPlugVolumeHandling", PLUGIN_VOLUMEHANDLING_IGNORE, iniFile)); + if(CSoundFile::s_DefaultPlugVolumeHandling > 2) CSoundFile::s_DefaultPlugVolumeHandling = PLUGIN_VOLUMEHANDLING_IGNORE; GetPrivateProfileString("Paths", "Songs_Directory", m_szModDir, m_szModDir, INIBUFFERSIZE, iniFile); GetPrivateProfileString("Paths", "Samples_Directory", m_szSmpDir, m_szSmpDir, INIBUFFERSIZE, iniFile); Modified: trunk/OpenMPT/mptrack/OrderToPatternTable.cpp =================================================================== --- trunk/OpenMPT/mptrack/OrderToPatternTable.cpp 2008-12-11 01:33:04 UTC (rev 237) +++ trunk/OpenMPT/mptrack/OrderToPatternTable.cpp 2008-12-11 19:53:02 UTC (rev 238) @@ -2,6 +2,8 @@ #include "sndfile.h" #include "ordertopatterntable.h" +#define str_SequenceTruncationNote (GetStrI18N((_TEXT("Module has sequence of length %u; it will be truncated to maximum supported length, %u.")))) + DWORD COrderToPatternTable::Unserialize(const BYTE* const src, const DWORD memLength) //------------------------------------------------------------------------- { @@ -17,6 +19,10 @@ if(s > 65000) return true; if(memLength < memPos+s*4) return memPos; + const uint32 nOriginalSize = s; + if(s > MPTM_SPECS.ordersMax) + s = MPTM_SPECS.ordersMax; + resize(s); for(size_t i = 0; i<s; i++, memPos +=4 ) { @@ -24,6 +30,7 @@ memcpy(&temp, src+memPos, 4); (*this)[i] = static_cast<PATTERNINDEX>(temp); } + memPos += 4*(nOriginalSize - s); return memPos; } @@ -186,7 +193,13 @@ { uint16 size; istrm.read(reinterpret_cast<char*>(&size), 2); - if(size > MPTM_SPECS.ordersMax) size = MPTM_SPECS.ordersMax; + if(size > MPTM_SPECS.ordersMax) + { + // Hack: Show message here if trying to load longer sequence than what is supported. + CString str; str.Format(str_SequenceTruncationNote, size, MPTM_SPECS.ordersMax); + ::MessageBox(0, str, "", MB_ICONWARNING); + size = MPTM_SPECS.ordersMax; + } m_rOrders.resize(size); if(size == 0) {m_rOrders.assign(MAX_ORDERS, m_rOrders.GetInvalidPatIndex()); return;} Modified: trunk/OpenMPT/mptrack/TuningDialog.cpp =================================================================== --- trunk/OpenMPT/mptrack/TuningDialog.cpp 2008-12-11 01:33:04 UTC (rev 237) +++ trunk/OpenMPT/mptrack/TuningDialog.cpp 2008-12-11 19:53:02 UTC (rev 238) @@ -1187,6 +1187,7 @@ HTREEITEM treeItemDestTC = m_TreeItemTuningItemMap.GetMapping_21(TUNINGTREEITEM(pTCdest)); DeleteTreeItem(pT); m_ModifiedTCs[pTCsrc] = true; + m_ModifiedTCs[pTCdest] = true; if(CTuningCollection::TransferTuning(pTCsrc, pTCdest, pT)) { MsgBox(IDS_OPERATION_FAIL, this, NULL, MB_OK); Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2008-12-11 01:33:04 UTC (rev 237) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2008-12-11 19:53:02 UTC (rev 238) @@ -33,6 +33,8 @@ #define str_MBtitle (GetStrI18N((_TEXT("Saving IT")))) #define str_tooMuchPatternData (GetStrI18N((_TEXT("Warning: File format limit was reached. Some pattern data may not get written to file.")))) #define str_pattern (GetStrI18N((_TEXT("pattern")))) +#define str_PatternSetTruncationNote (GetStrI18N((_TEXT("The module contains %u patterns but only %u patterns can be loaded in this OpenMPT version.")))) +#define str_SequenceTruncationNote (GetStrI18N((_TEXT("Module has sequence of length %u; it will be truncated to maximum supported length, %u.")))) static bool AreNonDefaultTuningsUsed(CSoundFile& sf) //-------------------------------------------------- @@ -1025,7 +1027,13 @@ } else { - if(nordsize > GetModSpecifications().ordersMax) nordsize = GetModSpecifications().ordersMax; + if(nordsize > GetModSpecifications().ordersMax) + { + CString str; + str.Format(str_SequenceTruncationNote, nordsize, GetModSpecifications().ordersMax); + CMainFrame::GetMainFrame()->MessageBox(str, 0, MB_ICONWARNING); + nordsize = GetModSpecifications().ordersMax; + } if(pifh->cwtv > 0x88A && pifh->cwtv <= 0x88D) dwMemPos += Order.Unserialize(lpStream+dwMemPos, dwMemLength-dwMemPos); @@ -1055,7 +1063,14 @@ dwMemPos += pifh->smpnum * 4; // Reading Patterns Offsets UINT patpossize = pifh->patnum; - if(patpossize > GetModSpecifications().patternsMax) patpossize = GetModSpecifications().patternsMax; + if(patpossize > GetModSpecifications().patternsMax) + { + // Hack: Note user here if file contains more patterns than what can be read. + CString str; + str.Format(str_PatternSetTruncationNote, patpossize, GetModSpecifications().patternsMax); + CMainFrame::GetMainFrame()->MessageBox(str, 0, MB_ICONWARNING); + patpossize = GetModSpecifications().patternsMax; + } patpos.resize(patpossize); patpossize *= 4; // <-> patpossize *= sizeof(DWORD); Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2008-12-11 01:33:04 UTC (rev 237) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2008-12-11 19:53:02 UTC (rev 238) @@ -387,6 +387,7 @@ CTuningCollection* CSoundFile::s_pTuningsSharedStandard(0); CTuningCollection* CSoundFile::s_pTuningsSharedLocal(0); +uint8 CSoundFile::s_DefaultPlugVolumeHandling = PLUGIN_VOLUMEHANDLING_IGNORE; CSoundFile::CSoundFile() : @@ -2757,7 +2758,7 @@ m_defaultInstrument.wPitchToTempoLock = 0; m_defaultInstrument.pTuning = m_defaultInstrument.s_DefaultTuning; m_defaultInstrument.nPluginVelocityHandling = PLUGIN_VELOCITYHANDLING_CHANNEL; - m_defaultInstrument.nPluginVolumeHandling = PLUGIN_VOLUMEHANDLING_DRYWET; + m_defaultInstrument.nPluginVolumeHandling = CSoundFile::s_DefaultPlugVolumeHandling; } Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2008-12-11 01:33:04 UTC (rev 237) +++ trunk/OpenMPT/soundlib/Sndfile.h 2008-12-11 19:53:02 UTC (rev 238) @@ -907,6 +907,7 @@ static UINT gnAGC, gnVolumeRampSamples, gnCPUUsage; static LPSNDMIXHOOKPROC gpSndMixHook; static PMIXPLUGINCREATEPROC gpMixPluginCreateProc; + static uint8 s_DefaultPlugVolumeHandling; Modified: trunk/OpenMPT/soundlib/tuning.cpp =================================================================== --- trunk/OpenMPT/soundlib/tuning.cpp 2008-12-11 01:33:04 UTC (rev 237) +++ trunk/OpenMPT/soundlib/tuning.cpp 2008-12-11 19:53:02 UTC (rev 238) @@ -490,7 +490,7 @@ //m_GroupRatio inStrm.read(reinterpret_cast<char*>(&pT->m_GroupRatio), sizeof(pT->m_GroupRatio)); - if(pT->m_GroupRatio <= 0) + if(pT->m_GroupRatio < 0) { delete pT; return 0; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2008-12-21 13:30:11
|
Revision: 239 http://modplug.svn.sourceforge.net/modplug/?rev=239&view=rev Author: relabsoluness Date: 2008-12-21 13:30:05 +0000 (Sun, 21 Dec 2008) Log Message: ----------- . Plugins: When playing with MIDI keyboard, plugins got a constant note velocity, not the actual velocity (bug 2754) . File opening: Added a couple of return value checks to reduce the change of crash when opening lots of files (bug 2546) . Pattern cleanup: Sequence wasn't in some cases cleaned properly for mptm. / Pattern cleanup: Clearing sequence after first '---' item is now optional. . S3M saving: Sequence of length 241-255 should now be cut to length 240 instead of ~16. / S3M saving: Saved sequence is no longer cut on first '---' item. / Sequence: Sequence scrolling behavior for S3M is now the same as for XM/IT/MPTM. / Song properties: Minor rephrasing in flag descriptions. Modified Paths: -------------- trunk/OpenMPT/mptrack/Childfrm.cpp trunk/OpenMPT/mptrack/Ctrl_seq.cpp trunk/OpenMPT/mptrack/Globals.cpp trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/dlg_misc.cpp trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/soundlib/Load_s3m.cpp Modified: trunk/OpenMPT/mptrack/Childfrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/Childfrm.cpp 2008-12-11 19:53:02 UTC (rev 238) +++ trunk/OpenMPT/mptrack/Childfrm.cpp 2008-12-21 13:30:05 UTC (rev 239) @@ -110,10 +110,10 @@ pModView->SetMDIParentFrame(m_hWnd); } - ChangeViewClass(RUNTIME_CLASS(CViewGlobals), pContext); + const BOOL bStatus = ChangeViewClass(RUNTIME_CLASS(CViewGlobals), pContext); - // it all worked, we now have a splitter window which contain two different views - return TRUE; + // If it all worked, we now have a splitter window which contain two different views + return bStatus; } //rewbs.varWindowSize Modified: trunk/OpenMPT/mptrack/Ctrl_seq.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2008-12-11 19:53:02 UTC (rev 238) +++ trunk/OpenMPT/mptrack/Ctrl_seq.cpp 2008-12-21 13:30:05 UTC (rev 239) @@ -116,13 +116,13 @@ UINT nPage; int nMax = 0; - if(pSndFile->TypeIsIT_MPT_XM()) - { // For IT/MPT/XM, show sequence until the last used item... - nMax = pSndFile->Order.GetLengthTailTrimmed(); + if(pSndFile->GetType() == MOD_TYPE_MOD) + { // With MOD, cut shown sequence to first '---' item... + nMax = pSndFile->Order.GetLengthFirstEmpty(); } else - { // ...and for MOD/S3M, cut shown sequence to first '---' item. - nMax = pSndFile->Order.GetLengthFirstEmpty(); + { // ...for S3M/IT/MPT/XM, show sequence until the last used item. + nMax = pSndFile->Order.GetLengthTailTrimmed(); } GetScrollInfo(SB_HORZ, &info, SIF_PAGE|SIF_RANGE); @@ -179,7 +179,10 @@ if(m_cxFont > 0) return static_cast<BYTE>(rcClient.right / m_cxFont); else - return static_cast<BYTE>(rcClient.right / GetFontWidth()); + { + const int nFontWidth = GetFontWidth(); + return (nFontWidth > 0) ? static_cast<BYTE>(rcClient.right / nFontWidth) : 0; + } } Modified: trunk/OpenMPT/mptrack/Globals.cpp =================================================================== --- trunk/OpenMPT/mptrack/Globals.cpp 2008-12-11 19:53:02 UTC (rev 238) +++ trunk/OpenMPT/mptrack/Globals.cpp 2008-12-21 13:30:05 UTC (rev 239) @@ -375,11 +375,16 @@ return FALSE; } if (!pDlg) return FALSE; + pDlg->SetDocument(GetDocument(), this); + pDlg->SetViewWnd(m_hWndView); + BOOL bStatus = pDlg->Create(nID, this); + if(bStatus == 0) // Creation failed. + { + delete pDlg; + return FALSE; + } m_nActiveDlg = nIndex; m_Pages[nIndex] = pDlg; - pDlg->SetDocument(GetDocument(), this); - pDlg->SetViewWnd(m_hWndView); - pDlg->Create(nID, this); } RecalcLayout(); pMainFrm->SetUserText(""); @@ -735,4 +740,4 @@ return HID_BASE_COMMAND + tbbn.idCommand; } return 0; -} \ No newline at end of file +} Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2008-12-11 19:53:02 UTC (rev 238) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2008-12-21 13:30:05 UTC (rev 239) @@ -882,8 +882,8 @@ if ((nPlugin) && (nPlugin <= MAX_MIXPLUGINS)) { IMixPlugin *pPlugin = m_SndFile.m_MixPlugins[nPlugin-1].pMixPlugin; - //if (pPlugin) pPlugin->MidiCommand(penv->nMidiChannel, penv->nMidiProgram, penv->wMidiBank, note, pChn->nVolume, MAX_BASECHANNELS); - if (pPlugin) pPlugin->MidiCommand(penv->nMidiChannel, penv->nMidiProgram, penv->wMidiBank, note, pChn->GetVSTVolume(), MAX_BASECHANNELS); + if (pPlugin) pPlugin->MidiCommand(penv->nMidiChannel, penv->nMidiProgram, penv->wMidiBank, note, pChn->nVolume, MAX_BASECHANNELS); + //if (pPlugin) pPlugin->MidiCommand(penv->nMidiChannel, penv->nMidiProgram, penv->wMidiBank, note, pChn->GetVSTVolume(), MAX_BASECHANNELS); } } } Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2008-12-11 19:53:02 UTC (rev 238) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2008-12-21 13:30:05 UTC (rev 239) @@ -509,6 +509,21 @@ vector<UINT> nPatRows(maxPatIndex, 0); vector<MODCOMMAND*> pPatterns(maxPatIndex, NULL); vector<BOOL> bPatUsed(maxPatIndex, false); + + const ORDERINDEX nLengthSub0 = m_SndFile.Order.GetLengthFirstEmpty(); + const ORDERINDEX nLengthUsed = m_SndFile.Order.GetLengthTailTrimmed(); + + // Flag to tell whether keeping sequence items which are after the first empty('---') order. + bool bKeepSubSequences = false; + + if(nLengthUsed != nLengthSub0) + { // There are used sequence items after first '---'; ask user whether to remove those. + if (CMainFrame::GetMainFrame()->MessageBox( + _TEXT("Do you want to remove sequence items which are after the first '---' item?"), + _TEXT("Sequence Cleanup"), MB_YESNO) != IDYES + ) + bKeepSubSequences = true; + } CHAR s[512]; BOOL bEnd = FALSE, bReordered = FALSE; @@ -522,7 +537,7 @@ if (n < maxPatIndex) { if (n >= maxpat) maxpat = n+1; - if (!bEnd) bPatUsed[n] = TRUE; + if (!bEnd || bKeepSubSequences) bPatUsed[n] = TRUE; } else if (n == m_SndFile.Order.GetInvalidPatIndex()) bEnd = TRUE; } nMinToRemove = 0; @@ -571,7 +586,7 @@ { if (nPatMap[n] > maxPatIndex) nPatMap[n] = nPats++; m_SndFile.Order[imap] = nPatMap[n]; - } else if (n == 0xFF) break; + } else if (n == m_SndFile.Order.GetInvalidPatIndex() && (bKeepSubSequences == false)) break; } // Add unused patterns at the end if ((!bRemove) || (!bWaste)) Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp =================================================================== --- trunk/OpenMPT/mptrack/dlg_misc.cpp 2008-12-11 19:53:02 UTC (rev 238) +++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2008-12-21 13:30:05 UTC (rev 239) @@ -277,10 +277,10 @@ { p->ShowWindow(XMorITorMPT); if(ITorMPT) - p->SetWindowText("0: Various playback changes for IT compatibility\n" - "1: Old instrument random variation behavior\n" - "2: Plugin volume command bug emulation"); - else if(XM) p->SetWindowText("0: Unused\n1: Unused\n2: Plugin volume command bug emulation"); + p->SetWindowText("1. Enable more IT compatible playback.\n" + "2. Use old random variation behavior for instruments.\n" + "3. Enable plugin volume command bug emulation."); + else if(XM) p->SetWindowText("1. Unused\n2. Unused\n3. Plugin volume command bug emulation"); } p = GetDlgItem(IDC_FLAGEDITTITLE); if(p) p->ShowWindow(XMorITorMPT); Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2008-12-11 19:53:02 UTC (rev 238) +++ trunk/OpenMPT/mptrack/mptrack.rc 2008-12-21 13:30:05 UTC (rev 239) @@ -975,9 +975,9 @@ WS_EX_STATICEDGE EDITTEXT IDC_EDIT5,7,209,58,13,ES_AUTOHSCROLL | ES_READONLY EDITTEXT IDC_EDIT6,7,225,58,13,ES_AUTOHSCROLL | ES_READONLY - LTEXT "Miscellaneous flags",IDC_FLAGEDITTITLE,9,150,65,12, - SS_CENTERIMAGE - EDITTEXT IDC_EDIT_FLAGS,80,150,70,12,ES_AUTOHSCROLL + LTEXT "Miscellaneous flags(0/1):",IDC_FLAGEDITTITLE,9,150,81, + 12,SS_CENTERIMAGE + EDITTEXT IDC_EDIT_FLAGS,93,150,70,12,ES_AUTOHSCROLL LTEXT "",IDC_FLAG_EXPLANATIONS,9,164,217,26 END Modified: trunk/OpenMPT/soundlib/Load_s3m.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_s3m.cpp 2008-12-11 19:53:02 UTC (rev 238) +++ trunk/OpenMPT/soundlib/Load_s3m.cpp 2008-12-21 13:30:05 UTC (rev 239) @@ -493,7 +493,15 @@ header[0x1B] = 0; header[0x1C] = 0x1A; header[0x1D] = 0x10; - nbo = (GetNumPatterns() + 15) & 0xF0; + // Changes to 1.17.02.53: + // -Try to save whole sequence instead of stopping on first empty order. + // -With more than 0xF0 orders, limit sequence to 0xF0 instead of just masking with 0xF0. + //TODO: Check whether the 0xF0 mask is correct. + // (there are two bytes reserved from the header, so why 0xF0 mask?). + //nbo = (GetNumPatterns() + 15) & 0xF0; + nbo = Order.GetLengthTailTrimmed() + 15; + if(nbo > 0xF0) nbo = 0xF0; + nbo = nbo & 0xF0; if (!nbo) nbo = 16; header[0x20] = nbo & 0xFF; header[0x21] = nbo >> 8; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2009-01-03 13:57:29
|
Revision: 241 http://modplug.svn.sourceforge.net/modplug/?rev=241&view=rev Author: relabsoluness Date: 2009-01-03 13:57:22 +0000 (Sat, 03 Jan 2009) Log Message: ----------- (Patches from Jojo) . XM player: Fix to handling a special case of Bxx and Dxx (bug 2769) / Updated DE_jojo-keymap. Modified Paths: -------------- trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb trunk/OpenMPT/soundlib/Snd_fx.cpp Modified: trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb =================================================================== --- trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb 2009-01-03 13:36:02 UTC (rev 240) +++ trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb 2009-01-03 13:57:22 UTC (rev 241) @@ -19,7 +19,7 @@ 0:1361:2:67:1 //Copy: Ctrl+C (KeyDown) 0:1361:2:45:1 //Copy: Ctrl+EINFG (KeyDown) 0:1362:2:86:1 //Paste: Ctrl+V (KeyDown) -0:1362:1:45:1 //Paste: Shift+EINFG (KeyDown) +0:1686:1:86:1 //Mix Paste (old IT Style): Shift+V (KeyDown) 0:1364:2:53:1 //SelectAll: Ctrl+5 (KeyDown) 0:1365:2:70:1 //Find: Ctrl+F (KeyDown) 0:1366:0:114:1 //Find Next: F3 (KeyDown) @@ -30,6 +30,7 @@ 0:1025:1:120:1 //View Comments: Shift+F9 (KeyDown) 0:1368:2:113:1 //Toggle Tree View: Ctrl+F2 (KeyDown) 0:1369:2:112:1 //View Options: Ctrl+F1 (KeyDown) +0:1781:2:114:1 //View MIDI mapping: Ctrl+F3 (KeyDown) 0:1370:0:112:1 //Help (to do): F1 (KeyDown) 0:1032:2:111:5 //Previous instrument: Ctrl+ (ZEHNERTASTATUR) (KeyDown|KeyHold) 0:1032:2:38:5 //Previous instrument: Ctrl+NACH-OBEN (KeyDown|KeyHold) @@ -69,6 +70,7 @@ 2:1685:2:9:1 //Switch to order list: Ctrl+TABULATOR (KeyDown) 2:1662:6:80:1 //Toggle channel's plugin editor: Ctrl+Alt+P (KeyDown) 2:1062:0:93:1 //Show note properties: ANWENDUNG (KeyDown) +2:1780:2:80:1 //Show playback time at current row: Ctrl+P (KeyDown) 2:1007:2:81:5 //Transpose +1: Ctrl+Q (KeyDown|KeyHold) 2:1008:2:65:5 //Transpose -1: Ctrl+A (KeyDown|KeyHold) 2:1009:3:81:5 //Transpose +12: Shift+Ctrl+Q (KeyDown|KeyHold) @@ -202,12 +204,13 @@ 5:1242:0:71:1 //Vol command - Portamento: G (KeyDown) 5:1243:0:70:1 //Vol command - Portamento Up: F (KeyDown) 5:1244:0:69:1 //Vol command - Portamento Down: E (KeyDown) -5:1245:1:186:1 //Vol command - Velocity: Shift+\xFC (KeyDown) +5:1245:1:190:1 //Vol command - Velocity: Shift+. (KeyDown) 5:1246:0:79:1 //Vol command - Offset: O (KeyDown) //----( Pattern Context [bottom] - FX Col (6) )------------ 6:1294:0:220:1 //FX midi macro slide: ZIRKUMFLEX (KeyDown) -6:1295:1:186:1 //FX pseudo-velocity (experimental): Shift+\xFC (KeyDown) +6:1295:1:190:1 //FX pseudo-velocity (experimental): Shift+. (KeyDown) +6:1666:0:191:1 //FX parameter extension command: # (KeyDown) //----( Pattern Context [bottom] - Param Col (7) )------------ 7:1247:0:48:1 //FX Param digit 0: 0 (KeyDown) @@ -240,7 +243,9 @@ //----( Sample Context [bottom] (8) )------------ 8:1380:2:84:1 //Trim sample around loop points: Ctrl+T (KeyDown) 8:1383:0:8:1 //Silence sample selection: R\xDCCK (KeyDown) +8:1384:1:78:1 //Normalise Sample: Shift+N (KeyDown) 8:1385:3:65:1 //Amplify Sample: Shift+Ctrl+A (KeyDown) +8:1385:2:77:1 //Amplify Sample: Ctrl+M (KeyDown) 8:1381:3:82:1 //Reverse sample: Shift+Ctrl+R (KeyDown) 8:1382:0:46:1 //Delete sample selection: ENTF (KeyDown) 8:1386:0:107:1 //Zoom Out: + (ZEHNERTASTATUR) (KeyDown) @@ -255,6 +260,11 @@ //----( Unknown Context (12) )------------ //----( Plugin GUI Context (13) )------------ +13:1763:0:37:1 //Previous plugin preset: NACH-LINKS (KeyDown) +13:1764:0:39:1 //Next plugin preset: NACH-RECHTS (KeyDown) +13:1782:0:38:1 //Plugin preset backward jump: NACH-OBEN (KeyDown) +13:1783:0:40:1 //Plugin preset forward jump: NACH-UNTEN (KeyDown) +13:1765:2:82:1 //Randomize plugin parameters: Ctrl+R (KeyDown) //----( General Context [top] (14) )------------ Modified: trunk/OpenMPT/soundlib/Snd_fx.cpp =================================================================== --- trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-01-03 13:36:02 UTC (rev 240) +++ trunk/OpenMPT/soundlib/Snd_fx.cpp 2009-01-03 13:57:22 UTC (rev 241) @@ -191,7 +191,8 @@ case CMD_POSITIONJUMP: positionJumpOnThisRow=true; nNextPattern = param; - if (!patternBreakOnThisRow) { + // see http://lpchip.com/modplug/viewtopic.php?t=2769 - FastTracker resets Dxx if Bxx is called _after_ Dxx + if (!patternBreakOnThisRow || (GetType() == MOD_TYPE_XM)) { nNextRow = 0; } if (bAdjust) @@ -1597,6 +1598,8 @@ //instant jumps - modifying behavior so that now position jumps //occurs also when pattern loop is enabled. } + // see http://lpchip.com/modplug/viewtopic.php?t=2769 - FastTracker resets Dxx if Bxx is called _after_ Dxx + if(GetType() == MOD_TYPE_XM) nBreakRow = 0; break; // Pattern Break This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2009-01-04 10:29:53
|
Revision: 242 http://modplug.svn.sourceforge.net/modplug/?rev=242&view=rev Author: relabsoluness Date: 2009-01-04 10:29:46 +0000 (Sun, 04 Jan 2009) Log Message: ----------- / General: Added a note to be shown when opening a file fails. / About box: Some changes. / SVN: Removed some include files. / PackageTemplate: Updated tuning file, added SoundTouch related files. Modified Paths: -------------- trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/mptrack/Vstplug.h trunk/OpenMPT/mptrack/res/MPTRACK.RC2 trunk/OpenMPT/packageTemplate/tunings/standard/std_tunings.tc Added Paths: ----------- trunk/OpenMPT/packageTemplate/SoundTouch/ trunk/OpenMPT/packageTemplate/SoundTouch/COPYING.TXT trunk/OpenMPT/packageTemplate/SoundTouch/README.html Removed Paths: ------------- trunk/OpenMPT/include/AEffect.h trunk/OpenMPT/include/ASIO.H trunk/OpenMPT/include/ASIOSYS.H trunk/OpenMPT/include/IASIODRV.H trunk/OpenMPT/include/aeffectx.h Deleted: trunk/OpenMPT/include/AEffect.h =================================================================== --- trunk/OpenMPT/include/AEffect.h 2009-01-03 13:57:22 UTC (rev 241) +++ trunk/OpenMPT/include/AEffect.h 2009-01-04 10:29:46 UTC (rev 242) @@ -1,197 +0,0 @@ -//------------------------------------------------------------------------------------------------------- -// VST Plug-Ins SDK -// Version 1.0 -// \xA9 2003, Steinberg Media Technologies, All Rights Reserved -//------------------------------------------------------------------------------------------------------- - -#ifndef __AEffect__ -#define __AEffect__ - -/* to create an Audio Effect for power pc's, create a - code resource - file type: 'aPcs' - resource type: 'aEff' - ppc header: none (raw pef) - - for windows, it's a .dll - - the only symbol searched for is: - AEffect *main(float (*audioMaster)(AEffect *effect, long opcode, long index, - long value, void *ptr, float opt)); -*/ - -#if CARBON -#if PRAGMA_STRUCT_ALIGN || __MWERKS__ - #pragma options align=mac68k -#endif -#else -#if PRAGMA_ALIGN_SUPPORTED || __MWERKS__ - #pragma options align=mac68k -#endif -#endif -#if defined __BORLANDC__ - #pragma -a8 -#elif defined(WIN32) || defined(__FLAT__) || defined CBUILDER - #pragma pack(push) - #pragma pack(8) - #define VSTCALLBACK __cdecl -#else - #define VSTCALLBACK -#endif - - -//------------------------------------------------- -// Misc. Definition -//------------------------------------------------- - -typedef struct AEffect AEffect; -typedef long (VSTCALLBACK *audioMasterCallback)(AEffect *effect, long opcode, long index, - long value, void *ptr, float opt); - -// prototype for plug-in main -// AEffect *main(audioMasterCallback audioMaster); - -// Four Character Constant -#define CCONST(a, b, c, d) \ - ((((long)a) << 24) | (((long)b) << 16) | (((long)c) << 8) | (((long)d) << 0)) - -// Magic Number -#define kEffectMagic CCONST ('V', 's', 't', 'P') - - -//------------------------------------------------- -// AEffect Structure -//------------------------------------------------- -struct AEffect -{ - long magic; // must be kEffectMagic ('VstP') - - long (VSTCALLBACK *dispatcher)(AEffect *effect, long opCode, long index, long value, - void *ptr, float opt); - - void (VSTCALLBACK *process)(AEffect *effect, float **inputs, float **outputs, long sampleframes); - - void (VSTCALLBACK *setParameter)(AEffect *effect, long index, float parameter); - float (VSTCALLBACK *getParameter)(AEffect *effect, long index); - - long numPrograms; // number of Programs - long numParams; // all programs are assumed to have numParams parameters - long numInputs; // number of Audio Inputs - long numOutputs; // number of Audio Outputs - - long flags; // see constants (Flags Bits) - - long resvd1; // reserved for Host, must be 0 (Dont use it) - long resvd2; // reserved for Host, must be 0 (Dont use it) - - long initialDelay; // for algorithms which need input in the first place - - long realQualities; // number of realtime qualities (0: realtime) - long offQualities; // number of offline qualities (0: realtime only) - float ioRatio; // input samplerate to output samplerate ratio, not used yet - - void *object; // for class access (see AudioEffect.hpp), MUST be 0 else! - void *user; // user access - - long uniqueID; // pls choose 4 character as unique as possible. (register it at Steinberg Web) - // this is used to identify an effect for save+load - long version; // (example 1100 for version 1.1.0.0) - - void (VSTCALLBACK *processReplacing)(AEffect *effect, float **inputs, float **outputs, long sampleframes); - - char future[60]; // pls zero -}; - -//------------------------------------------------- -// Flags Bits -//------------------------------------------------- - -#define effFlagsHasEditor 1 // if set, is expected to react to editor messages -#define effFlagsHasClip 2 // return > 1. in getVu() if clipped -#define effFlagsHasVu 4 // return vu value in getVu(); > 1. means clipped -#define effFlagsCanMono 8 // if numInputs == 2, makes sense to be used for mono in -#define effFlagsCanReplacing 16 // supports in place output (processReplacing() exsists) -#define effFlagsProgramChunks 32 // program data are handled in formatless chunks - -//------------------------------------------------- -// Dispatcher OpCodes -//------------------------------------------------- - -enum -{ - effOpen = 0, // initialise - effClose, // exit, release all memory and other resources! - - effSetProgram, // program no in <value> - effGetProgram, // return current program no. - effSetProgramName, // user changed program name (max 24 char + 0) to as passed in string - effGetProgramName, // stuff program name (max 24 char + 0) into string - - effGetParamLabel, // stuff parameter <index> label (max 8 char + 0) into string - // (examples: sec, dB, type) - effGetParamDisplay, // stuff parameter <index> textual representation into string - // (examples: 0.5, -3, PLATE) - effGetParamName, // stuff parameter <index> label (max 8 char + 0) into string - // (examples: Time, Gain, RoomType) - effGetVu, // called if (flags & (effFlagsHasClip | effFlagsHasVu)) - - // system - effSetSampleRate, // in opt (float value in Hz; for example 44100.0Hz) - effSetBlockSize, // in value (this is the maximun size of an audio block, - // pls check sampleframes in process call) - effMainsChanged, // the user has switched the 'power on' button to - // value (0 off, else on). This only switches audio - // processing; you should flush delay buffers etc. - - // editor - effEditGetRect, // stuff rect (top, left, bottom, right) into ptr - effEditOpen, // system dependant Window pointer in ptr - effEditClose, // no arguments - effEditDraw, // draw method, ptr points to rect (MAC Only) - effEditMouse, // index: x, value: y (MAC Only) - effEditKey, // system keycode in value - effEditIdle, // no arguments. Be gentle! - effEditTop, // window has topped, no arguments - effEditSleep, // window goes to background - - effIdentify, // returns 'NvEf' - effGetChunk, // host requests pointer to chunk into (void**)ptr, byteSize returned - effSetChunk, // plug-in receives saved chunk, byteSize passed - - effNumOpcodes -}; - -//------------------------------------------------- -// AudioMaster OpCodes -//------------------------------------------------- - -enum -{ - audioMasterAutomate = 0, // index, value, returns 0 - audioMasterVersion, // VST Version supported (for example 2200 for VST 2.2) - audioMasterCurrentId, // Returns the unique id of a plug that's currently - // loading - audioMasterIdle, // Call application idle routine (this will - // call effEditIdle for all open editors too) - audioMasterPinConnected // Inquire if an input or output is beeing connected; - // index enumerates input or output counting from zero, - // value is 0 for input and != 0 otherwise. note: the - // return value is 0 for <true> such that older versions - // will always return true. -}; - -#if CARBON -#if PRAGMA_STRUCT_ALIGN || __MWERKS__ - #pragma options align=reset -#endif -#else -#if PRAGMA_ALIGN_SUPPORTED || __MWERKS__ - #pragma options align=reset -#elif defined(WIN32) || defined(__FLAT__) - #pragma pack(pop) -#elif defined __BORLANDC__ - #pragma -a- -#endif -#endif - -#endif // __AEffect__ Deleted: trunk/OpenMPT/include/ASIO.H =================================================================== --- trunk/OpenMPT/include/ASIO.H 2009-01-03 13:57:22 UTC (rev 241) +++ trunk/OpenMPT/include/ASIO.H 2009-01-04 10:29:46 UTC (rev 242) @@ -1,955 +0,0 @@ -//--------------------------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------------------------- - -/* - Steinberg Audio Stream I/O API - (c) 1997 - 1999, Steinberg Soft- und Hardware GmbH - - ASIO Interface Specification v 2.0 - - basic concept is an i/o synchronous double-buffer scheme: - - on bufferSwitch(index == 0), host will read/write: - - after ASIOStart(), the - read first input buffer A (index 0) - | will be invalid (empty) - * ------------------------ - |------------------------|-----------------------| - | | | - | Input Buffer A (0) | Input Buffer B (1) | - | | | - |------------------------|-----------------------| - | | | - | Output Buffer A (0) | Output Buffer B (1) | - | | | - |------------------------|-----------------------| - * ------------------------- - | before calling ASIOStart(), - write host will have filled output - buffer B (index 1) already - - *please* take special care of proper statement of input - and output latencies (see ASIOGetLatencies()), these - control sequencer sync accuracy - -*/ - -//--------------------------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------------------------- - -/* - -prototypes summary: - -ASIOError ASIOInit(ASIODriverInfo *info); -ASIOError ASIOExit(void); -ASIOError ASIOStart(void); -ASIOError ASIOStop(void); -ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels); -ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency); -ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity); -ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate); -ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate); -ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate); -ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources); -ASIOError ASIOSetClockSource(long reference); -ASIOError ASIOGetSamplePosition (ASIOSamples *sPos, ASIOTimeStamp *tStamp); -ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info); -ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels, - long bufferSize, ASIOCallbacks *callbacks); -ASIOError ASIODisposeBuffers(void); -ASIOError ASIOControlPanel(void); -void *ASIOFuture(long selector, void *params); -ASIOError ASIOOutputReady(void); - -*/ - -//--------------------------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------------------------- - -#ifndef __ASIO_H -#define __ASIO_H - -// force 4 byte alignment -#if defined(_MSC_VER) && !defined(__MWERKS__) -#pragma pack(push,4) -#elif PRAGMA_ALIGN_SUPPORTED -#pragma options align = native -#endif - -//- - - - - - - - - - - - - - - - - - - - - - - - - -// Type definitions -//- - - - - - - - - - - - - - - - - - - - - - - - - - -// number of samples data type is 64 bit integer -#if NATIVE_INT64 - typedef long long int ASIOSamples; -#else - typedef struct ASIOSamples { - unsigned long hi; - unsigned long lo; - } ASIOSamples; -#endif - -// Timestamp data type is 64 bit integer, -// Time format is Nanoseconds. -#if NATIVE_INT64 - typedef long long int ASIOTimeStamp ; -#else - typedef struct ASIOTimeStamp { - unsigned long hi; - unsigned long lo; - } ASIOTimeStamp; -#endif - -// Samplerates are expressed in IEEE 754 64 bit double float, -// native format as host computer -#if IEEE754_64FLOAT - typedef double ASIOSampleRate; -#else - typedef struct ASIOSampleRate { - char ieee[8]; - } ASIOSampleRate; -#endif - -// Boolean values are expressed as long -typedef long ASIOBool; -enum { - ASIOFalse = 0, - ASIOTrue = 1 -}; - -// Sample Types are expressed as long -typedef long ASIOSampleType; -enum { - ASIOSTInt16MSB = 0, - ASIOSTInt24MSB = 1, // used for 20 bits as well - ASIOSTInt32MSB = 2, - ASIOSTFloat32MSB = 3, // IEEE 754 32 bit float - ASIOSTFloat64MSB = 4, // IEEE 754 64 bit double float - - // these are used for 32 bit data buffer, with different alignment of the data inside - // 32 bit PCI bus systems can be more easily used with these - ASIOSTInt32MSB16 = 8, // 32 bit data with 18 bit alignment - ASIOSTInt32MSB18 = 9, // 32 bit data with 18 bit alignment - ASIOSTInt32MSB20 = 10, // 32 bit data with 20 bit alignment - ASIOSTInt32MSB24 = 11, // 32 bit data with 24 bit alignment - - ASIOSTInt16LSB = 16, - ASIOSTInt24LSB = 17, // used for 20 bits as well - ASIOSTInt32LSB = 18, - ASIOSTFloat32LSB = 19, // IEEE 754 32 bit float, as found on Intel x86 architecture - ASIOSTFloat64LSB = 20, // IEEE 754 64 bit double float, as found on Intel x86 architecture - - // these are used for 32 bit data buffer, with different alignment of the data inside - // 32 bit PCI bus systems can more easily used with these - ASIOSTInt32LSB16 = 24, // 32 bit data with 18 bit alignment - ASIOSTInt32LSB18 = 25, // 32 bit data with 18 bit alignment - ASIOSTInt32LSB20 = 26, // 32 bit data with 20 bit alignment - ASIOSTInt32LSB24 = 27 // 32 bit data with 24 bit alignment -}; - -//- - - - - - - - - - - - - - - - - - - - - - - - - -// Error codes -//- - - - - - - - - - - - - - - - - - - - - - - - - - -typedef long ASIOError; -enum { - ASE_OK = 0, // This value will be returned whenever the call succeeded - ASE_SUCCESS = 0x3f4847a0, // unique success return value for ASIOFuture calls - ASE_NotPresent = -1000, // hardware input or output is not present or available - ASE_HWMalfunction, // hardware is malfunctioning (can be returned by any ASIO function) - ASE_InvalidParameter, // input parameter invalid - ASE_InvalidMode, // hardware is in a bad mode or used in a bad mode - ASE_SPNotAdvancing, // hardware is not running when sample position is inquired - ASE_NoClock, // sample clock or rate cannot be determined or is not present - ASE_NoMemory // not enough memory for completing the request -}; - -//--------------------------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------------------------- - -//- - - - - - - - - - - - - - - - - - - - - - - - - -// Time Info support -//- - - - - - - - - - - - - - - - - - - - - - - - - - -typedef struct ASIOTimeCode -{ - double speed; // speed relation (fraction of nominal speed) - // optional; set to 0. or 1. if not supported - ASIOSamples timeCodeSamples; // time in samples - unsigned long flags; // some information flags (see below) - char future[64]; -} ASIOTimeCode; - -typedef enum ASIOTimeCodeFlags -{ - kTcValid = 1, - kTcRunning = 1 << 1, - kTcReverse = 1 << 2, - kTcOnspeed = 1 << 3, - kTcStill = 1 << 4, - - kTcSpeedValid = 1 << 8 -} ASIOTimeCodeFlags; - -typedef struct AsioTimeInfo -{ - double speed; // absolute speed (1. = nominal) - ASIOTimeStamp systemTime; // system time related to samplePosition, in nanoseconds - // on mac, must be derived from Microseconds() (not UpTime()!) - // on windows, must be derived from timeGetTime() - ASIOSamples samplePosition; - ASIOSampleRate sampleRate; // current rate - unsigned long flags; // (see below) - char reserved[12]; -} AsioTimeInfo; - -typedef enum AsioTimeInfoFlags -{ - kSystemTimeValid = 1, // must always be valid - kSamplePositionValid = 1 << 1, // must always be valid - kSampleRateValid = 1 << 2, - kSpeedValid = 1 << 3, - - kSampleRateChanged = 1 << 4, - kClockSourceChanged = 1 << 5 -} AsioTimeInfoFlags; - -typedef struct ASIOTime // both input/output -{ - long reserved[4]; // must be 0 - struct AsioTimeInfo timeInfo; // required - struct ASIOTimeCode timeCode; // optional, evaluated if (timeCode.flags & kTcValid) -} ASIOTime; - -/* - -using time info: -it is recommended to use the new method with time info even if the asio -device does not support timecode; continuous calls to ASIOGetSamplePosition -and ASIOGetSampleRate are avoided, and there is a more defined relationship -between callback time and the time info. - -see the example below. -to initiate time info mode, after you have received the callbacks pointer in -ASIOCreateBuffers, you will call the asioMessage callback with kAsioSupportsTimeInfo -as the argument. if this returns 1, host has accepted time info mode. -now host expects the new callback bufferSwitchTimeInfo to be used instead -of the old bufferSwitch method. the ASIOTime structure is assumed to be valid -and accessible until the callback returns. - -using time code: -if the device supports reading time code, it will call host's asioMessage callback -with kAsioSupportsTimeCode as the selector. it may then fill the according -fields and set the kTcValid flag. -host will call the future method with the kAsioEnableTimeCodeRead selector when -it wants to enable or disable tc reading by the device. you should also support -the kAsioCanTimeInfo and kAsioCanTimeCode selectors in ASIOFuture (see example). - -note: -the AsioTimeInfo/ASIOTimeCode pair is supposed to work in both directions. -as a matter of convention, the relationship between the sample -position counter and the time code at buffer switch time is -(ignoring offset between tc and sample pos when tc is running): - -on input: sample 0 -> input buffer sample 0 -> time code 0 -on output: sample 0 -> output buffer sample 0 -> time code 0 - -this means that for 'real' calculations, one has to take into account -the according latencies. - -example: - -ASIOTime asioTime; - -in createBuffers() -{ - memset(&asioTime, 0, sizeof(ASIOTime)); - AsioTimeInfo* ti = &asioTime.timeInfo; - ti->sampleRate = theSampleRate; - ASIOTimeCode* tc = &asioTime.timeCode; - tc->speed = 1.; - timeInfoMode = false; - canTimeCode = false; - if(callbacks->asioMessage(kAsioSupportsTimeInfo, 0, 0, 0) == 1) - { - timeInfoMode = true; -#if kCanTimeCode - if(callbacks->asioMessage(kAsioSupportsTimeCode, 0, 0, 0) == 1) - canTimeCode = true; -#endif - } -} - -void switchBuffers(long doubleBufferIndex, bool processNow) -{ - if(timeInfoMode) - { - AsioTimeInfo* ti = &asioTime.timeInfo; - ti->flags = kSystemTimeValid | kSamplePositionValid | kSampleRateValid; - ti->systemTime = theNanoSeconds; - ti->samplePosition = theSamplePosition; - if(ti->sampleRate != theSampleRate) - ti->flags |= kSampleRateChanged; - ti->sampleRate = theSampleRate; - -#if kCanTimeCode - if(canTimeCode && timeCodeEnabled) - { - ASIOTimeCode* tc = &asioTime.timeCode; - tc->timeCodeSamples = tcSamples; // tc in samples - tc->flags = kTcValid | kTcRunning | kTcOnspeed; // if so... - } - ASIOTime* bb = callbacks->bufferSwitchTimeInfo(&asioTime, doubleBufferIndex, processNow ? ASIOTrue : ASIOFalse); -#else - callbacks->bufferSwitchTimeInfo(&asioTime, doubleBufferIndex, processNow ? ASIOTrue : ASIOFalse); -#endif - } - else - callbacks->bufferSwitch(doubleBufferIndex, ASIOFalse); -} - -ASIOError ASIOFuture(long selector, void *params) -{ - switch(selector) - { - case kAsioEnableTimeCodeRead: - timeCodeEnabled = true; - return ASE_SUCCESS; - case kAsioDisableTimeCodeRead: - timeCodeEnabled = false; - return ASE_SUCCESS; - case kAsioCanTimeInfo: - return ASE_SUCCESS; - #if kCanTimeCode - case kAsioCanTimeCode: - return ASE_SUCCESS; - #endif - } - return ASE_NotPresent; -}; - -*/ - -//- - - - - - - - - - - - - - - - - - - - - - - - - -// application's audio stream handler callbacks -//- - - - - - - - - - - - - - - - - - - - - - - - - - -typedef struct ASIOCallbacks -{ - void (*bufferSwitch) (long doubleBufferIndex, ASIOBool directProcess); - // bufferSwitch indicates that both input and output are to be processed. - // the current buffer half index (0 for A, 1 for B) determines - // - the output buffer that the host should start to fill. the other buffer - // will be passed to output hardware regardless of whether it got filled - // in time or not. - // - the input buffer that is now filled with incoming data. Note that - // because of the synchronicity of i/o, the input always has at - // least one buffer latency in relation to the output. - // directProcess suggests to the host whether it should immedeately - // start processing (directProcess == ASIOTrue), or whether its process - // should be deferred because the call comes from a very low level - // (for instance, a high level priority interrupt), and direct processing - // would cause timing instabilities for the rest of the system. If in doubt, - // directProcess should be set to ASIOFalse. - // Note: bufferSwitch may be called at interrupt time for highest efficiency. - - void (*sampleRateDidChange) (ASIOSampleRate sRate); - // gets called when the AudioStreamIO detects a sample rate change - // If sample rate is unknown, 0 is passed (for instance, clock loss - // when externally synchronized). - - long (*asioMessage) (long selector, long value, void* message, double* opt); - // generic callback for various purposes, see selectors below. - // note this is only present if the asio version is 2 or higher - - ASIOTime* (*bufferSwitchTimeInfo) (ASIOTime* params, long doubleBufferIndex, ASIOBool directProcess); - // new callback with time info. makes ASIOGetSamplePosition() and various - // calls to ASIOGetSampleRate obsolete, - // and allows for timecode sync etc. to be preferred; will be used if - // the driver calls asioMessage with selector kAsioSupportsTimeInfo. -} ASIOCallbacks; - -// asioMessage selectors -enum -{ - kAsioSelectorSupported = 1, // selector in <value>, returns 1L if supported, - // 0 otherwise - kAsioEngineVersion, // returns engine (host) asio implementation version, - // 2 or higher - kAsioResetRequest, // request driver reset. if accepted, this - // will close the driver (ASIO_Exit() ) and - // re-open it again (ASIO_Init() etc). some - // drivers need to reconfigure for instance - // when the sample rate changes, or some basic - // changes have been made in ASIO_ControlPanel(). - // returns 1L; note the request is merely passed - // to the application, there is no way to determine - // if it gets accepted at this time (but it usually - // will be). - kAsioBufferSizeChange, // not yet supported, will currently always return 0L. - // for now, use kAsioResetRequest instead. - // once implemented, the new buffer size is expected - // in <value>, and on success returns 1L - kAsioResyncRequest, // the driver went out of sync, such that - // the timestamp is no longer valid. this - // is a request to re-start the engine and - // slave devices (sequencer). returns 1 for ok, - // 0 if not supported. - kAsioLatenciesChanged, // the drivers latencies have changed. The engine - // will refetch the latencies. - kAsioSupportsTimeInfo, // if host returns true here, it will expect the - // callback bufferSwitchTimeInfo to be called instead - // of bufferSwitch - kAsioSupportsTimeCode, // supports time code reading/writing - - kAsioSupportsInputMonitor, // supports input monitoring - - kAsioNumMessageSelectors -}; - -//--------------------------------------------------------------------------------------------------- -//--------------------------------------------------------------------------------------------------- - -//- - - - - - - - - - - - - - - - - - - - - - - - - -// (De-)Construction -//- - - - - - - - - - - - - - - - - - - - - - - - - - -typedef struct ASIODriverInfo -{ - long asioVersion; // currently, 2 - long driverVersion; // driver specific - char name[32]; - char errorMessage[124]; - void *sysRef; // on input: system reference - // (Windows: application main window handle, Mac & SGI: 0) -} ASIODriverInfo; - -ASIOError ASIOInit(ASIODriverInfo *info); -/* Purpose: - Initialize the AudioStreamIO. - Parameter: - info: pointer to an ASIODriver structure: - - asioVersion: - - on input, the host version. *** Note *** this is 0 for earlier asio - implementations, and the asioMessage callback is implemeted - only if asioVersion is 2 or greater. sorry but due to a design fault - the driver doesn't have access to the host version in ASIOInit :-( - added selector for host (engine) version in the asioMessage callback - so we're ok from now on. - - on return, asio implementation version. - older versions are 1 - if you support this version (namely, ASIO_outputReady() ) - this should be 2 or higher. also see the note in - ASIO_getTimeStamp() ! - - version: on return, the driver version (format is driver specific) - - name: on return, a null-terminated string containing the driver's name - - error message: on return, should contain a user message describing - the type of error that occured during ASIOInit(), if any. - - sysRef: platform specific - Returns: - If neither input nor output is present ASE_NotPresent - will be returned. - ASE_NoMemory, ASE_HWMalfunction are other possible error conditions -*/ - -ASIOError ASIOExit(void); -/* Purpose: - Terminates the AudioStreamIO. - Parameter: - None. - Returns: - If neither input nor output is present ASE_NotPresent - will be returned. - Notes: this implies ASIOStop() and ASIODisposeBuffers(), - meaning that no host callbacks must be accessed after ASIOExit(). -*/ - -//- - - - - - - - - - - - - - - - - - - - - - - - - -// Start/Stop -//- - - - - - - - - - - - - - - - - - - - - - - - - - -ASIOError ASIOStart(void); -/* Purpose: - Start input and output processing synchronously. - This will - - reset the sample counter to zero - - start the hardware (both input and output) - The first call to the hosts' bufferSwitch(index == 0) then tells - the host to read from input buffer A (index 0), and start - processing to output buffer A while output buffer B (which - has been filled by the host prior to calling ASIOStart()) - is possibly sounding (see also ASIOGetLatencies()) - Parameter: - None. - Returns: - If neither input nor output is present, ASE_NotPresent - will be returned. - If the hardware fails to start, ASE_HWMalfunction will be returned. - Notes: - There is no restriction on the time that ASIOStart() takes - to perform (that is, it is not considered a realtime trigger). -*/ - -ASIOError ASIOStop(void); -/* Purpose: - Stops input and output processing altogether. - Parameter: - None. - Returns: - If neither input nor output is present ASE_NotPresent - will be returned. - Notes: - On return from ASIOStop(), the driver must in no - case call the hosts' bufferSwitch() routine. -*/ - -//- - - - - - - - - - - - - - - - - - - - - - - - - -// Inquiry methods and sample rate -//- - - - - - - - - - - - - - - - - - - - - - - - - - -ASIOError ASIOGetChannels(long *numInputChannels, long *numOutputChannels); -/* Purpose: - Returns number of individual input/output channels. - Parameter: - numInputChannels will hold the number of available input channels - numOutputChannels will hold the number of available output channels - Returns: - If no input/output is present ASE_NotPresent will be returned. - If only inputs, or only outputs are available, the according - other parameter will be zero, and ASE_OK is returned. -*/ - -ASIOError ASIOGetLatencies(long *inputLatency, long *outputLatency); -/* Purpose: - Returns the input and output latencies. This includes - device specific delays, like FIFOs etc. - Parameter: - inputLatency will hold the 'age' of the first sample frame - in the input buffer when the hosts reads it in bufferSwitch() - (this is theoretical, meaning it does not include the overhead - and delay between the actual physical switch, and the time - when bufferSitch() enters). - This will usually be the size of one block in sample frames, plus - device specific latencies. - - outputLatency will specify the time between the buffer switch, - and the time when the next play buffer will start to sound. - The next play buffer is defined as the one the host starts - processing after (or at) bufferSwitch(), indicated by the - index parameter (0 for buffer A, 1 for buffer B). - It will usually be either one block, if the host writes directly - to a dma buffer, or two or more blocks if the buffer is 'latched' by - the driver. As an example, on ASIOStart(), the host will have filled - the play buffer at index 1 already; when it gets the callback (with - the parameter index == 0), this tells it to read from the input - buffer 0, and start to fill the play buffer 0 (assuming that now - play buffer 1 is already sounding). In this case, the output - latency is one block. If the driver decides to copy buffer 1 - at that time, and pass it to the hardware at the next slot (which - is most commonly done, but should be avoided), the output latency - becomes two blocks instead, resulting in a total i/o latency of at least - 3 blocks. As memory access is the main bottleneck in native dsp processing, - and to acheive less latency, it is highly recommended to try to avoid - copying (this is also why the driver is the owner of the buffers). To - summarize, the minimum i/o latency can be acheived if the input buffer - is processed by the host into the output buffer which will physically - start to sound on the next time slice. Also note that the host expects - the bufferSwitch() callback to be accessed for each time slice in order - to retain sync, possibly recursively; if it fails to process a block in - time, it will suspend its operation for some time in order to recover. - Returns: - If no input/output is present ASE_NotPresent will be returned. -*/ - -ASIOError ASIOGetBufferSize(long *minSize, long *maxSize, long *preferredSize, long *granularity); -/* Purpose: - Returns min, max, and preferred buffer sizes for input/output - Parameter: - minSize will hold the minimum buffer size - maxSize will hold the maxium possible buffer size - preferredSize will hold the preferred buffer size (a size which - best fits performance and hardware requirements) - granularity will hold the granularity at which buffer sizes - may differ. Usually, the buffer size will be a power of 2; - in this case, granularity will hold -1 on return, signalling - possible buffer sizes starting from minSize, increased in - powers of 2 up to maxSize. - Returns: - If no input/output is present ASE_NotPresent will be returned. - Notes: - When minimum and maximum buffer size are equal, - the preferred buffer size has to be the same value as well; granularity - should be 0 in this case. -*/ - -ASIOError ASIOCanSampleRate(ASIOSampleRate sampleRate); -/* Purpose: - Inquires the hardware for the available sample rates. - Parameter: - sampleRate is the rate in question. - Returns: - If the inquired sample rate is not supported, ASE_NoClock will be returned. - If no input/output is present ASE_NotPresent will be returned. -*/ -ASIOError ASIOGetSampleRate(ASIOSampleRate *currentRate); -/* Purpose: - Get the current sample Rate. - Parameter: - currentRate will hold the current sample rate on return. - Returns: - If sample rate is unknown, sampleRate will be 0 and ASE_NoClock will be returned. - If no input/output is present ASE_NotPresent will be returned. - Notes: -*/ - -ASIOError ASIOSetSampleRate(ASIOSampleRate sampleRate); -/* Purpose: - Set the hardware to the requested sample Rate. If sampleRate == 0, - enable external sync. - Parameter: - sampleRate: on input, the requested rate - Returns: - If sampleRate is unknown ASE_NoClock will be returned. - If the current clock is external, and sampleRate is != 0, - ASE_InvalidMode will be returned - If no input/output is present ASE_NotPresent will be returned. - Notes: -*/ - -typedef struct ASIOClockSource -{ - long index; // as used for ASIOSetClockSource() - long associatedChannel; // for instance, S/PDIF or AES/EBU - long associatedGroup; // see channel groups (ASIOGetChannelInfo()) - ASIOBool isCurrentSource; // ASIOTrue if this is the current clock source - char name[32]; // for user selection -} ASIOClockSource; - -ASIOError ASIOGetClockSources(ASIOClockSource *clocks, long *numSources); -/* Purpose: - Get the available external audio clock sources - Parameter: - clocks points to an array of ASIOClockSource structures: - - index: this is used to identify the clock source - when ASIOSetClockSource() is accessed, should be - an index counting from zero - - associatedInputChannel: the first channel of an associated - input group, if any. - - associatedGroup: the group index of that channel. - groups of channels are defined to seperate for - instance analog, S/PDIF, AES/EBU, ADAT connectors etc, - when present simultaniously. Note that associated channel - is enumerated according to numInputs/numOutputs, means it - is independant from a group (see also ASIOGetChannelInfo()) - inputs are associated to a clock if the physical connection - transfers both data and clock (like S/PDIF, AES/EBU, or - ADAT inputs). if there is no input channel associated with - the clock source (like Word Clock, or internal oscillator), both - associatedChannel and associatedGroup should be set to -1. - - isCurrentSource: on exit, ASIOTrue if this is the current clock - source, ASIOFalse else - - name: a null-terminated string for user selection of the available sources. - numSources: - on input: the number of allocated array members - on output: the number of available clock sources, at least - 1 (internal clock generator). - Returns: - If no input/output is present ASE_NotPresent will be returned. - Notes: -*/ - -ASIOError ASIOSetClockSource(long index); -/* Purpose: - Set the audio clock source - Parameter: - index as obtained from an inquiry to ASIOGetClockSources() - Returns: - If no input/output is present ASE_NotPresent will be returned. - If the clock can not be selected because an input channel which - carries the current clock source is active, ASE_InvalidMode - *may* be returned (this depends on the properties of the driver - and/or hardware). - Notes: - Should *not* return ASE_NoClock if there is no clock signal present - at the selected source; this will be inquired via ASIOGetSampleRate(). - It should call the host callback procedure sampleRateHasChanged(), - if the switch causes a sample rate change, or if no external clock - is present at the selected source. -*/ - -ASIOError ASIOGetSamplePosition (ASIOSamples *sPos, ASIOTimeStamp *tStamp); -/* Purpose: - Inquires the sample position/time stamp pair. - Parameter: - sPos will hold the sample position on return. The sample - position is reset to zero when ASIOStart() gets called. - tStamp will hold the system time when the sample position - was latched. - Returns: - If no input/output is present, ASE_NotPresent will be returned. - If there is no clock, ASE_SPNotAdvancing will be returned. - Notes: - - in order to be able to synchronise properly, - the sample position / time stamp pair must refer to the current block, - that is, the engine will call ASIOGetSamplePosition() in its bufferSwitch() - callback and expect the time for the current block. thus, when requested - in the very first bufferSwitch after ASIO_Start(), the sample position - should be zero, and the time stamp should refer to the very time where - the stream was started. it also means that the sample position must be - block aligned. the driver must ensure proper interpolation if the system - time can not be determined for the block position. the driver is responsible - for precise time stamps as it usually has most direct access to lower - level resources. proper behaviour of ASIO_GetSamplePosition() and ASIO_GetLatencies() - are essential for precise media synchronization! -*/ - -typedef struct ASIOChannelInfo -{ - long channel; // on input, channel index - ASIOBool isInput; // on input - ASIOBool isActive; // on exit - long channelGroup; // dto - ASIOSampleType type; // dto - char name[32]; // dto -} ASIOChannelInfo; - -ASIOError ASIOGetChannelInfo(ASIOChannelInfo *info); -/* Purpose: - retreive information about the nature of a channel - Parameter: - info: pointer to a ASIOChannelInfo structure with - - channel: on input, the channel index of the channel in question. - - isInput: on input, ASIOTrue if info for an input channel is - requested, else output - - channelGroup: on return, the channel group that the channel - belongs to. For drivers which support different types of - channels, like analog, S/PDIF, AES/EBU, ADAT etc interfaces, - there should be a reasonable grouping of these types. Groups - are always independant form a channel index, that is, a channel - index always counts from 0 to numInputs/numOutputs regardless - of the group it may belong to. - There will always be at least one group (group 0). Please - also note that by default, the host may decide to activate - channels 0 and 1; thus, these should belong to the most - useful type (analog i/o, if present). - - type: on return, contains the sample type of the channel - - isActive: on return, ASIOTrue if channel is active as it was - installed by ASIOCreateBuffers(), ASIOFalse else - - name: describing the type of channel in question. Used to allow - for user selection, and enabling of specific channels. examples: - "Analog In", "SPDIF Out" etc - Returns: - If no input/output is present ASE_NotPresent will be returned. - Notes: - If possible, the string should be organised such that the first - characters are most significantly describing the nature of the - port, to allow for identification even if the view showing the - port name is too small to display more than 8 characters, for - instance. -*/ - -//- - - - - - - - - - - - - - - - - - - - - - - - - -// Buffer preparation -//- - - - - - - - - - - - - - - - - - - - - - - - - - -typedef struct ASIOBufferInfo -{ - ASIOBool isInput; // on input: ASIOTrue: input, else output - long channelNum; // on input: channel index - void *buffers[2]; // on output: double buffer addresses -} ASIOBufferInfo; - -ASIOError ASIOCreateBuffers(ASIOBufferInfo *bufferInfos, long numChannels, - long bufferSize, ASIOCallbacks *callbacks); - -/* Purpose: - Allocates input/output buffers for all input and output channels to be activated. - Parameter: - bufferInfos is a pointer to an array of ASIOBufferInfo structures: - - isInput: on input, ASIOTrue if the buffer is to be allocated - for an input, output buffer else - - channelNum: on input, the index of the channel in question - (counting from 0) - - buffers: on exit, 2 pointers to the halves of the channels' double-buffer. - the size of the buffer(s) of course depend on both the ASIOSampleType - as obtained from ASIOGetChannelInfo(), and bufferSize - numChannels is the sum of all input and output channels to be created; - thus bufferInfos is a pointer to an array of numChannels ASIOBufferInfo - structures. - bufferSize selects one of the possible buffer sizes as obtained from - ASIOGetBufferSizes(). - callbacks is a pointer to an ASIOCallbacks structure. - Returns: - If not enough memory is available ASE_NoMemory will be returned. - If no input/output is present ASE_NotPresent will be returned. - If bufferSize is not supported, or one or more of the bufferInfos elements - contain invalid settings, ASE_InvalidMode will be returned. - Notes: - If individual channel selection is not possible but requested, - the driver has to handle this. namely, bufferSwitch() will only - have filled buffers of enabled outputs. If possible, processing - and buss activities overhead should be avoided for channels which - were not enabled here. -*/ - -ASIOError ASIODisposeBuffers(void); -/* Purpose: - Releases all buffers for the device. - Parameter: - None. - Returns: - If no buffer were ever prepared, ASE_InvalidMode will be returned. - If no input/output is present ASE_NotPresent will be returned. - Notes: - This implies ASIOStop(). -*/ - -ASIOError ASIOControlPanel(void); -/* Purpose: - request the driver to start a control panel component - for device specific user settings. This will not be - accessed on some platforms (where the component is accessed - instead). - Parameter: - None. - Returns: - If no panel is available ASE_NotPresent will be returned. - Actually, the return code is ignored. - Notes: - if the user applied settings which require a re-configuration - of parts or all of the enigine and/or driver (such as a change of - the block size), the asioMessage callback can be used (see - ASIO_Callbacks). -*/ - -ASIOError ASIOFuture(long selector, void *params); -/* Purpose: - various - Parameter: - selector: operation Code as to be defined. zero is reserved for - testing purposes. - params: depends on the selector; usually pointer to a structure - for passing and retreiving any type and amount of parameters. - Returns: - the return value is also selector dependant. if the selector - is unknown, ASE_InvalidParameter should be returned to prevent - further calls with this selector. on success, ASE_SUCCESS - must be returned (note: ASE_OK is *not* sufficient!) - Notes: - see selectors defined below. -*/ - -enum -{ - kAsioEnableTimeCodeRead = 1, // no arguments - kAsioDisableTimeCodeRead, // no arguments - kAsioSetInputMonitor, // ASIOInputMonitor* in params - kAsioTransport, // ASIOTransportParameters* in params - kAsioSetInputGain, // ASIOChannelControls* in params, apply gain - kAsioGetInputMeter, // ASIOChannelControls* in params, fill meter - kAsioSetOutputGain, // ASIOChannelControls* in params, apply gain - kAsioGetOutputMeter, // ASIOChannelControls* in params, fill meter - kAsioCanInputMonitor, // no arguments for kAsioCanXXX selectors - kAsioCanTimeInfo, - kAsioCanTimeCode, - kAsioCanTransport, - kAsioCanInputGain, - kAsioCanInputMeter, - kAsioCanOutputGain, - kAsioCanOutputMeter -}; - -typedef struct ASIOInputMonitor -{ - long input; // this input was set to monitor (or off), -1: all - long output; // suggested output for monitoring the input (if so) - long gain; // suggested gain, ranging 0 - 0x7fffffffL (-inf to +12 dB) - ASIOBool state; // ASIOTrue => on, ASIOFalse => off - long pan; // suggested pan, 0 => all left, 0x7fffffff => right -} ASIOInputMonitor; - -typedef struct ASIOChannelControls -{ - long channel; // on input, channel index - ASIOBool isInput; // on input - long gain; // on input, ranges 0 thru 0x7fffffff - long meter; // on return, ranges 0 thru 0x7fffffff - char future[32]; -} ASIOChannelControls; - -typedef struct ASIOTransportParameters -{ - long command; // see enum below - ASIOSamples samplePosition; - long track; - long trackSwitches[16]; // 512 tracks on/off - char future[64]; -} ASIOTransportParameters; - -enum -{ - kTransStart = 1, - kTransStop, - kTransLocate, // to samplePosition - kTransPunchIn, - kTransPunchOut, - kTransArmOn, // track - kTransArmOff, // track - kTransMonitorOn, // track - kTransMonitorOff, // track - kTransArm, // trackSwitches - kTransMonitor // trackSwitches -}; - -ASIOError ASIOOutputReady(void); -/* Purpose: - this tells the driver that the host has completed processing - the output buffers. if the data format required by the hardware - differs from the supported asio formats, but the hardware - buffers are DMA buffers, the driver will have to convert - the audio stream data; as the bufferSwitch callback is - usually issued at dma block switch time, the driver will - have to convert the *previous* host buffer, which increases - the output latency by one block. - when the host finds out that ASIOOutputReady() returns - true, it will issue this call whenever it completed - output processing. then the driver can convert the - host data directly to the dma buffer to be played next, - reducing output latency by one block. - another way to look at it is, that the buffer switch is called - in order to pass the *input* stream to the host, so that it can - process the input into the output, and the output stream is passed - to the driver when the host has completed its process. - Parameter: - None - Returns: - only if the above mentioned scenario is given, and a reduction - of output latency can be acheived by this mechanism, should - ASE_OK be returned. otherwise (and usually), ASE_NotPresent - should be returned in order to prevent further calls to this - function. note that the host may want to determine if it is - to use this when the system is not yet fully initialized, so - ASE_OK should always be returned if the mechanism makes sense. - Notes: - please remeber to adjust ASIOGetLatencies() according to - whether ASIOOutputReady() was ever called or not, if your - driver supports this scenario. - also note that the engine may fail to call ASIO_OutputReady() - in time in overload cases. as already mentioned, bufferSwitch - should be called for every block regardless of whether a block - could be processed in time. -*/ - -// restore old alignment -#if defined(_MSC_VER) && !defined(__MWERKS__) -#pragma pack(pop) -#elif PRAGMA_ALIGN_SUPPORTED -#pragma options align = reset -#endif - -#endif - Deleted: trunk/OpenMPT/include/ASIOSYS.H =================================================================== --- trunk/OpenMPT/include/ASIOSYS.H 2009-01-03 13:57:22 UTC (rev 241) +++ trunk/OpenMPT/include/ASIOSYS.H 2009-01-04 10:29:46 UTC (rev 242) @@ -1,82 +0,0 @@ -#ifndef __asiosys__ - #define __asiosys__ - - #ifdef WIN32 - #undef MAC - #define PPC 0 - #define WINDOWS 1 - #define SGI 0 - #define SUN 0 - #define LINUX 0 - #define BEOS 0 - - #define NATIVE_INT64 0 - #define IEEE754_64FLOAT 1 - - #elif BEOS - #define MAC 0 - #define PPC 0 - #define WINDOWS 0 - #define PC 0 - #define SGI 0 - #define SUN 0 - #define LINUX 0 - - #define NATIVE_INT64 0 - #define IEEE754_64FLOAT 1 - - #ifndef DEBUG - #define DEBUG 0 - #if DEBUG - void DEBUGGERMESSAGE(char *string); - #else - #define DEBUGGERMESSAGE(a) - #endif - #endif - - #elif SGI - #define MAC 0 - #define PPC 0 - #define WINDOWS 0 - #define PC 0 - #define SUN 0 - #define LINUX 0 - #define BEOS 0 - - #define NATIVE_INT64 0 - #define IEEE754_64FLOAT 1 - - #ifndef DEBUG - #define DEBUG 0 - #if DEBUG - void DEBUGGERMESSAGE(char *string); - #else - #define DEBUGGERMESSAGE(a) - #endif - #endif - - #else // MAC - - #define MAC 1 - #define PPC 1 - #define WINDOWS 0 - #define PC 0 - #define SGI 0 - #define SUN 0 - #define LINUX 0 - #define BEOS 0 - - #define NATIVE_INT64 0 - #define IEEE754_64FLOAT 1 - - #ifndef DEBUG - #define DEBUG 0 - #if DEBUG - void DEBUGGERMESSAGE(char *string); - #else - #define DEBUGGERMESSAGE(a) - #endif - #endif - #endif - -#endif Deleted: trunk/OpenMPT/include/IASIODRV.H =================================================================== --- trunk/OpenMPT/include/IASIODRV.H 2009-01-03 13:57:22 UTC (rev 241) +++ trunk/OpenMPT/include/IASIODRV.H 2009-01-04 10:29:46 UTC (rev 242) @@ -1,37 +0,0 @@ -#include "asiosys.h" -#include "asio.h" - -/* Forward Declarations */ - -#ifndef __ASIODRIVER_FWD_DEFINED__ -#define __ASIODRIVER_FWD_DEFINED__ -typedef interface IASIO IASIO; -#endif /* __ASIODRIVER_FWD_DEFINED__ */ - -interface IASIO : public IUnknown -{ - - virtual ASIOBool init(void *sysHandle) = 0; - virtual void getDriverName(char *name) = 0; - virtual long getDriverVersion() = 0; - virtual void getErrorMessage(char *string) = 0; - virtual ASIOError start() = 0; - virtual ASIOError stop() = 0; - virtual ASIOError getChannels(long *numInputChannels, long *numOutputChannels) = 0; - virtual ASIOError getLatencies(long *inputLatency, long *outputLatency) = 0; - virtual ASIOError getBufferSize(long *minSize, long *maxSize, - long *preferredSize, long *granularity) = 0; - virtual ASIOError canSampleRate(ASIOSampleRate sampleRate) = 0; - virtual ASIOError getSampleRate(ASIOSampleRate *sampleRate) = 0; - virtual ASIOError setSampleRate(ASIOSampleRate sampleRate) = 0; - virtual ASIOError getClockSources(ASIOClockSource *clocks, long *numSources) = 0; - virtual ASIOError setClockSource(long reference) = 0; - virtual ASIOError getSamplePosition(ASIOSamples *sPos, ASIOTimeStamp *tStamp) = 0; - virtual ASIOError getChannelInfo(ASIOChannelInfo *info) = 0; - virtual ASIOError createBuffers(ASIOBufferInfo *bufferInfos, long numChannels, - long bufferSize, ASIOCallbacks *callbacks) = 0; - virtual ASIOError disposeBuffers() = 0; - virtual ASIOError controlPanel() = 0; - virtual ASIOError future(long selector,void *opt) = 0; - virtual ASIOError outputReady() = 0; -}; Deleted: trunk/OpenMPT/include/aeffectx.h =================================================================== --- trunk/OpenMPT/include/aeffectx.h 2009-01-03 13:57:22 UTC (rev 241) +++ trunk/OpenMPT/include/aeffectx.h 2009-01-04 10:29:46 UTC (rev 242) @@ -1,1007 +0,0 @@ -//------------------------------------------------------------------------------------------------------- -// VST Plug-Ins SDK -// Version 2.3 Extension -// \xA9 2003, Steinberg Media Technologies, All Rights Reserved -//------------------------------------------------------------------------------------------------------- - -#ifndef __aeffectx__ -#define __aeffectx__ - -#ifndef __AEffect__ -#include "AEffect.h" -#endif - -#include <string.h> // for strcpy - -#if PRAGMA_STRUCT_ALIGN || __MWERKS__ - #pragma options align=mac68k -#elif defined __BORLANDC__ - #pragma -a8 -#elif defined(WIN32) || defined(__FLAT__) - #pragma pack(push) - #pragma pack(8) -#endif - -enum {VSTEVENT_QUEUE_LEN=256}; - - -//------------------------------------------------- -// VstEvent -//------------------------------------------------- - -typedef struct VstEvent VstEvent; -typedef struct VstMidiEvent VstMidiEvent; -typedef struct VstEvents VstEvents; - -struct VstEvent // a generic timestamped event -{ - long type; // see enum below - long byteSize; // of this event, excl. type and byteSize - long deltaFrames; // sample frames related to the current block start sample position - long flags; // generic flags, none defined yet (0) - - char data[16]; // size may vary but is usually 16 -}; - -//----VstEvent Types------------------------------- -enum -{ - kVstMidiType = 1, // midi event, can be cast as VstMidiEvent (see below) - kVstAudioType, // audio - kVstVideoType, // video - kVstParameterType, // parameter - kVstTriggerType, // trigger - kVstSysExType // midi system exclusive - // ...etc -}; - -struct VstEvents // a block of events for the current audio block -{ - long numEvents; - long reserved; // zero - VstEvent* events[VSTEVENT_QUEUE_LEN]; // variable -}; - -//---Defined Events-------------------------------- -struct VstMidiEvent // to be casted from a VstEvent -{ - long type; // kVstMidiType - long byteSize; // 24 - long deltaFrames; // sample frames related to the current block start sample position - long flags; // none defined yet - - long noteLength; // (in sample frames) of entire note, if available, else 0 - long noteOffset; // offset into note from note start if available, else 0 - - char midiData[4]; // 1 thru 3 midi bytes; midiData[3] is reserved (zero) - char detune; // -64 to +63 cents; for scales other than 'well-tempered' ('microtuning') - char noteOffVelocity; - char reserved1; // zero - char reserved2; // zero -}; - - -//------------------------------------------------- -// VstTimeInfo -//------------------------------------------------- - -typedef struct VstTimeInfo VstTimeInfo; - -// VstTimeInfo as requested via audioMasterGetTime (getTimeInfo()) -// refers to the current time slice. note the new slice is -// already started when processEvents() is called - -struct VstTimeInfo -{ - double samplePos; // current location - double sampleRate; - double nanoSeconds; // system time - double ppqPos; // 1 ppq - double tempo; // in bpm - double barStartPos; // last bar start, in 1 ppq - double cycleStartPos; // 1 ppq - double cycleEndPos; // 1 ppq - long timeSigNumerator; // time signature - long timeSigDenominator; - long smpteOffset; - long smpteFrameRate; // 0:24, 1:25, 2:29.97, 3:30, 4:29.97 df, 5:30 df - long samplesToNextClock; // midi clock resolution (24 ppq), can be negative - long flags; // see below -}; - -enum -{ - kVstTransportChanged = 1, // Indicates that Playing, Cycle or Recording has changed - kVstTransportPlaying = 1 << 1, - kVstTransportCycleActive = 1 << 2, - kVstTransportRecording = 1 << 3, - - kVstAutomationWriting = 1 << 6, - kVstAutomationReading = 1 << 7, - - // flags which indicate which of the fields in this VstTimeInfo - // are valid; samplePos and sampleRate are always valid - kVstNanosValid = 1 << 8, - kVstPpqPosValid = 1 << 9, - kVstTempoValid = 1 << 10, - kVstBarsValid = 1 << 11, - kVstCyclePosValid = 1 << 12, // start and end - kVstTimeSigValid = 1 << 13, - kVstSmpteValid = 1 << 14, - kVstClockValid = 1 << 15 -}; - -//------------------------------------------------- -// Variable IO for Offline Processing -//------------------------------------------------- - -typedef struct VstVariableIo VstVariableIo; - -struct VstVariableIo -{ - float **inputs; - float **outputs; - long numSamplesInput; - long numSamplesOutput; - long *numSamplesInputProcessed; - long *numSamplesOutputProcessed; -}; - -//------------------------------------------------- -// AudioMaster OpCodes -//------------------------------------------------- - -enum -{ - //---from here VST 2.0 extension opcodes------------------------------------------------------ - // VstEvents + VstTimeInfo - audioMasterWantMidi = audioMasterPinConnected + 2, // <value> is a filter which is currently ignored - audioMasterGetTime, // returns const VstTimeInfo* (or 0 if not supported) - // <value> should contain a mask indicating which fields are required - // (see valid masks above), as some items may require extensive - // conversions - audioMasterProcessEvents, // VstEvents* in <ptr> - audioMasterSetTime, // VstTimenfo* in <ptr>, filter in <value>, not supported - audioMasterTempoAt, // returns tempo (in bpm * 10000) at sample frame location passed in <value> - - // parameters - audioMasterGetNumAutomatableParameters, - audioMasterGetParameterQuantization, // returns the integer value for +1.0 representation, - // or 1 if full single float precision is maintained - // in automation. parameter index in <value> (-1: all, any) - // connections, configuration - audioMasterIOChanged, // numInputs and/or numOutputs has changed - audioMasterNeedIdle, // plug needs idle calls (outside its editor window) - audioMasterSizeWindow, // index: width, value: height - audioMasterGetSampleRate, - audioMasterGetBlockSize, - audioMasterGetInputLatency, - audioMasterGetOutputLatency, - audioMasterGetPreviousPlug, // input pin in <value> (-1: first to come), returns cEffect* - audioMasterGetNextPlug, // output pin in <value> (-1: first to come), returns cEffect* - - // realtime info - audioMasterWillReplaceOrAccumulate, // returns: 0: not supported, 1: replace, 2: accumulate - audioMasterGetCurrentProcessLevel, // returns: 0: not supported, - // 1: currently in user thread (gui) - // 2: currently in audio thread (where process is called) - // 3: currently in 'sequencer' thread (midi, timer etc) - // 4: currently offline processing and thus in user thread - // other: not defined, but probably pre-empting user thread. - audioMasterGetAutomationState, // returns 0: not supported, 1: off, 2:read, 3:write, 4:read/write - - // offline - audioMasterOfflineStart, - audioMasterOfflineRead, // ptr points to offline structure, see below. return 0: error, 1 ok - audioMasterOfflineWrite, // same as read - audioMasterOfflineGetCurrentPass, - audioMasterOfflineGetCurrentMetaPass, - - // other - audioMasterSetOutputSampleRate, // for variable i/o, sample rate in <opt> - audioMasterGetSpeakerArrangement, // result in ret - audioMasterGetOutputSpeakerArrangement = audioMasterGetSpeakerArrangement, - audioMasterGetVendorString, // fills <ptr> with a string identifying the vendor (max 64 char) - audioMasterGetProductString, // fills <ptr> with a string with product name (max 64 char) - audioMasterGetVendorVersion, // returns vendor-specific version - audioMasterVendorSpecific, // no definition, vendor specific handling - audioMasterSetIcon, // void* in <ptr>, format not defined yet - audioMasterCanDo, // string in ptr, see below - audioMasterGetLanguage, // see enum - audioMasterOpenWindow, // returns platform specific ptr - audioMasterCloseWindow, // close window, platform specific handle in <ptr> - audioMasterGetDirectory, // get plug directory, FSSpec on MAC, else char* - audioMasterUpdateDisplay, // something has changed, update 'multi-fx' display - - //---from here VST 2.1 extension opcodes------------------------------------------------------ - audioMasterBeginEdit, // begin of automation session (when mouse down), parameter index in <index> - audioMasterEndEdit, // end of automation session (when mouse up), parameter index in <index> - audioMasterOpenFileSelector, // open a fileselector window with VstFileSelect* in <ptr> - - //---from here VST 2.2 extension opcodes------------------------------------------------------ - audioMasterCloseFileSelector, // close a fileselector operation with VstFileSelect* in <ptr>: Must be always called after an open ! - audioMasterEditFile, // open an editor for audio (defined by XML text in ptr) - audioMasterGetChunkFile, // get the native path of currently loading bank or project - // (called from writeChunk) void* in <ptr> (char[2048], or sizeof(FSSpec)) - - //---from here VST 2.3 extension opcodes------------------------------------------------------ - audioMasterGetInputSpeakerArrangement // result a VstSpeakerArrangement in ret -}; - -//------------------------------------------------- -// Language -//------------------------------------------------- - -enum VstHostLanguage -{ - kVstLangEnglish = 1, - kVstLangGerman, - kVstLangFrench, - kVstLangItalian, - kVstLangSpanish, - kVstLangJapanese -}; - -//------------------------------------------------- -// Dispatcher OpCodes -//------------------------------------------------- - -enum -{ - //---from here VST 2.0 extension opcodes--------------------------------------------------------- - // VstEvents - effProcessEvents = effSetChunk + 1, // VstE... [truncated message content] |
From: <rel...@us...> - 2009-01-10 07:52:33
|
Revision: 243 http://modplug.svn.sourceforge.net/modplug/?rev=243&view=rev Author: relabsoluness Date: 2009-01-10 07:52:25 +0000 (Sat, 10 Jan 2009) Log Message: ----------- Pattern, minor fixes and tweaks: . Undo fixes (didn't properly handle playback positions/multichannel record, set redundant undo points) . Fixes to macro command recording (see rev. 240) (didn't set modified, didn't update GUI) . Param record in plugs GUI wrote commands even when pattern record was off. . Fixed chord detection when row spacing was enabled. / Some refactoring. MIDI/plug / When passing MIDI to plug, documents will now be set modified since MIDI data may change parameters. . Modifying plug params with MIDI mapping didn't set document modified. / Misc: Changes to internet links. . Misc: Fix to possible crash when closing modified document between timer ticks (very rare). (patch from Jojo) / Minor GUI tweaks especially in the setup dialogs. Modified Paths: -------------- trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Mpt_midi.cpp trunk/OpenMPT/mptrack/View_ins.cpp trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/mptrack/View_pat.h trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/mptrack/pattern.h trunk/OpenMPT/mptrack/patternContainer.h trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/soundlib/midi.h Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2009-01-04 10:29:46 UTC (rev 242) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2009-01-10 07:52:25 UTC (rev 243) @@ -99,6 +99,8 @@ ON_COMMAND_EX(ID_NETLINK_HANDBOOK, OnInternetLink) ON_COMMAND_EX(ID_NETLINK_FORUMS, OnInternetLink) ON_COMMAND_EX(ID_NETLINK_PLUGINS, OnInternetLink) + ON_COMMAND_EX(ID_NETLINK_OPENMPTWIKI_GERMAN, OnInternetLink) + ON_COMMAND_EX(ID_NETLINK_MODARCHIVE, OnInternetLink) ON_CBN_SELCHANGE(IDC_COMBO_BASEOCTAVE, OnOctaveChanged) ON_UPDATE_COMMAND_UI(ID_MIDI_RECORD, OnUpdateMidiRecord) ON_UPDATE_COMMAND_UI(ID_INDICATOR_TIME, OnUpdateTime) @@ -2258,6 +2260,10 @@ //------------------------------------------------- { if (pModDoc == m_pModPlaying) PauseMod(); + + // Make sure that OnTimer() won't try to set the closed document modified anymore. + if (pModDoc == m_pJustModifiedDoc) m_pJustModifiedDoc = 0; + m_wndTree.OnDocumentClosed(pModDoc); } @@ -2665,12 +2671,14 @@ { // case ID_NETLINK_MODPLUG: pszURL = "http://www.modplug.com"; break; case ID_NETLINK_OPENMPTWIKI:pszURL = "http://openmpt.xwiki.com/"; break; - case ID_NETLINK_UT: pszURL = "http://www.united-trackers.org"; break; - case ID_NETLINK_OSMUSIC: pszURL = "http://www.osmusic.net/"; break; +// case ID_NETLINK_UT: pszURL = "http://www.united-trackers.org"; break; +// case ID_NETLINK_OSMUSIC: pszURL = "http://www.osmusic.net/"; break; // case ID_NETLINK_HANDBOOK: pszURL = "http://www.modplug.com/mods/handbook/handbook.htm"; break; case ID_NETLINK_MPTFR: pszURL = "http://mpt.new.fr/"; break; case ID_NETLINK_FORUMS: pszURL = "http://www.lpchip.com/modplug"; break; case ID_NETLINK_PLUGINS: pszURL = "http://www.kvraudio.com"; break; + case ID_NETLINK_MODARCHIVE: pszURL = "http://modarchive.org/"; break; + case ID_NETLINK_OPENMPTWIKI_GERMAN: pszURL = "http://sagamusix.de/openmpt/Hauptseite"; break; } if (pszURL) return CTrackApp::OpenURL(pszURL); return FALSE; Modified: trunk/OpenMPT/mptrack/Mpt_midi.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mpt_midi.cpp 2009-01-04 10:29:46 UTC (rev 242) +++ trunk/OpenMPT/mptrack/Mpt_midi.cpp 2009-01-10 07:52:25 UTC (rev 243) @@ -294,6 +294,7 @@ IMixPlugin* pPlug = m_rSndFile.m_MixPlugins[plugindex-1].pMixPlugin; if(!pPlug) continue; pPlug->SetZxxParameter(param, (midimsg >> 16) & 0x7F); + CMainFrame::GetMainFrame()->ThreadSafeSetModified(m_rSndFile.GetpModDoc()); } } } Modified: trunk/OpenMPT/mptrack/View_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_ins.cpp 2009-01-04 10:29:46 UTC (rev 242) +++ trunk/OpenMPT/mptrack/View_ins.cpp 2009-01-10 07:52:25 UTC (rev 243) @@ -2614,7 +2614,14 @@ { const INSTRUMENTINDEX instr = m_nInstrument; IMixPlugin* plug = pSndFile->GetInstrumentPlugin(instr); - if(plug) plug->MidiSend(dwMidiData); + if(plug) + { + plug->MidiSend(dwMidiData); + // Sending midi may modify the plug. For now, if MIDI data + // is not active sensing, set modified. + if(dwMidiData != MIDISTATUS_ACTIVESENSING) + CMainFrame::GetMainFrame()->ThreadSafeSetModified(pModDoc); + } } break; } Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2009-01-04 10:29:46 UTC (rev 242) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-01-10 07:52:25 UTC (rev 243) @@ -602,14 +602,14 @@ //-------------------------------------------------------- { CModDoc *pModDoc = GetDocument(); - int x,y,cx,cy; + UINT nChnBeg, nRowBeg, nChnEnd, nRowEnd; - x = (dwBegin & 0xFFFF) >> 3; - y = (dwBegin >> 16); - cx = ((dwEnd & 0xFFFF) >> 3) - x + 1; - cy = (dwEnd >> 16) - y + 1; - if ((x < 0) || (y < 0) || (cx < 1) || (cy < 1)) return FALSE; - if (pModDoc) return pModDoc->PrepareUndo(m_nPattern, x, y, cx, cy); + nChnBeg = GetChanFromCursor(dwBegin); + nRowBeg = GetRowFromCursor(dwBegin); + nChnEnd = GetChanFromCursor(dwEnd); + nRowEnd = GetRowFromCursor(dwEnd); + if( (nChnEnd < nChnBeg) || (nRowEnd < nRowBeg) ) return FALSE; + if (pModDoc) return pModDoc->PrepareUndo(m_nPattern, nChnBeg, nRowBeg, nChnEnd-nChnBeg+1, nRowEnd-nRowBeg+1); return FALSE; } @@ -2823,7 +2823,8 @@ //-------------------------------------------------------------------------- { CModDoc *pModDoc = GetDocument(); - if (!m_bRecord || !pModDoc) { + //if (!m_bRecord || !pModDoc) { + if (!IsEditingEnabled() || !pModDoc) { return 0; } CSoundFile *pSndFile = pModDoc->GetSoundFile(); @@ -2831,17 +2832,18 @@ return 0; } - MODCOMMAND *pRow; - PrepareUndo(m_dwBeginSel, m_dwEndSel); - //Work out where to put the new data - UINT nChn = (m_dwCursor & 0xFFFF) >> 3; - bool usePlaybackPosition = (m_dwStatus & PATSTATUS_FOLLOWSONG) && //work out whether we should use - (CMainFrame::GetMainFrame()->GetFollowSong(pModDoc) == m_hWnd) && //player engine position or - !(pSndFile->IsPaused()); //edit cursor position - UINT nRow = usePlaybackPosition?pSndFile->m_nRow:m_nRow; - pRow = pSndFile->Patterns[m_nPattern] + nRow*pSndFile->m_nChannels + nChn; + const UINT nChn = GetChanFromCursor(m_dwCursor); + const bool bUsePlaybackPosition = IsLiveRecord(*pModDoc, *pSndFile); + ROWINDEX nRow = m_nRow; + PATTERNINDEX nPattern = m_nPattern; + if(bUsePlaybackPosition == true) + SetEditPos(*pSndFile, nRow, nPattern, pSndFile->m_nRow, pSndFile->m_nPattern); + pModDoc->PrepareUndo(nPattern, nChn, nRow, 1, 1); + + MODCOMMAND *pRow = pSndFile->Patterns[nPattern].GetpModCommand(nRow, nChn); + // TODO: Is the right plugin active? Move to a chan with the right plug // Probably won't do this - finish fluctuator implementation instead. @@ -2956,15 +2958,24 @@ // Checking whether to record MIDI controller change as MIDI macro change. if((CMainFrame::m_dwMidiSetup & MIDISETUP_MIDIMACROCONTROL) && IsEditingEnabled()) { - CModDoc* const pModdoc = GetDocument(); - if(pModDoc != 0) - { - MODCOMMAND *p = pModdoc->GetSoundFile()->Patterns[m_nPattern].GetpModCommand(m_nRow, GetChanFromCursor(m_dwCursor)); - if(p->command == 0 || p->command == CMD_SMOOTHMIDI) - { // Write command only if there's no existing command or already a smooth midi macro command. - p->command = CMD_SMOOTHMIDI; - p->param = nByte2; - } + // Note: No undo for these modifications. + const bool bLiveRecord = IsLiveRecord(*pModDoc, *pSndFile); + ROWINDEX nRow = m_nRow; + PATTERNINDEX nPat = m_nPattern; + if(bLiveRecord) + SetEditPos(*pSndFile, nRow, nPat, pSndFile->m_nRow, pSndFile->m_nPattern); + + const CHANNELINDEX nChn = GetChanFromCursor(m_dwCursor); + MODCOMMAND *p = pSndFile->Patterns[nPat].GetpModCommand(nRow, nChn); + if(p->command == 0 || p->command == CMD_SMOOTHMIDI || p->command == CMD_MIDI) + { // Write command only if there's no existing command or already a midi macro command. + p->command = CMD_SMOOTHMIDI; + p->param = nByte2; + pMainFrm->ThreadSafeSetModified(pModDoc); + + // Update GUI only if not recording live. + if(bLiveRecord == false) + InvalidateRow(nRow); } } @@ -2995,7 +3006,15 @@ { const UINT instr = GetCurrentInstrument(); IMixPlugin* plug = pSndFile->GetInstrumentPlugin(instr); - if(plug) plug->MidiSend(dwMidiData); + if(plug) + { + plug->MidiSend(dwMidiData); + // Sending midi may modify the plug. For now, if MIDI data + // is not active sensing, set modified. + if(dwMidiData != MIDISTATUS_ACTIVESENSING) + pMainFrm->ThreadSafeSetModified(pModDoc); + } + } break; } @@ -3689,12 +3708,21 @@ //} } } -void CViewPattern::TempStopNote(int note, bool fromMidi) -//------------------------------------------------------ + + +void CViewPattern::TempStopNote(int note, bool fromMidi, const bool bChordMode) +//----------------------------------------------------------------------------- { CModDoc *pModDoc = GetDocument(); - bool isSplit = (note < m_nSplitNote); + CSoundFile *pSndFile = pModDoc->GetSoundFile(); CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); + + // Get playback edit positions from play engine here in case they are needed below. + const ROWINDEX nRowPlayback = pSndFile->m_nRow; + const UINT nTick = pSndFile->m_nTickCount; + const PATTERNINDEX nPatPlayback = pSndFile->m_nPattern; + + const bool isSplit = (note < m_nSplitNote); if (pModDoc) { UINT ins = 0; @@ -3707,27 +3735,30 @@ } if (!ins) ins = GetCurrentInstrument(); if (!ins) ins = m_nFoundInstrument; + if(bChordMode == true) + { + m_dwStatus &= ~PATSTATUS_CHORDPLAYING; + pModDoc->NoteOff(0, TRUE, ins, m_dwCursor & 0xFFFF); + } + else + pModDoc->NoteOff(note, FALSE, ins, GetChanFromCursor(m_dwCursor)); //pModDoc->NoteOff(note, TRUE, ins, (m_dwCursor & 0xFFFF) >> 3); - pModDoc->NoteOff(note, FALSE, ins, GetChanFromCursor(m_dwCursor)); - } //Enter note off in pattern? if ((note < 1) || (note > NOTE_MAX)) return; - if ((m_dwCursor & 7) > 1 && !fromMidi) + if ((m_dwCursor & 7) > 1 && (bChordMode || !fromMidi)) return; if (!pModDoc || !pMainFrm || !(IsEditingEnabled())) return; - CSoundFile *pSndFile = pModDoc->GetSoundFile(); - UINT nChn = GetChanFromCursor(m_dwCursor); - PrepareUndo(m_dwBeginSel, m_dwEndSel); + const bool bIsLiveRecord = IsLiveRecord(*pMainFrm, *pModDoc, *pSndFile); + const CHANNELINDEX nChnCursor = GetChanFromCursor(m_dwCursor); + BYTE* activeNoteMap = isSplit ? splitActiveNoteChannel : activeNoteChannel; - CHANNELINDEX releaseChan = activeNoteMap[note]; - if (releaseChan > pSndFile->GetNumChannels()) - releaseChan = nChn; + const CHANNELINDEX nChn = (activeNoteMap[note] < pSndFile->GetNumChannels()) ? activeNoteMap[note] : nChnCursor; activeNoteMap[note] = 0xFF; //unlock channel @@ -3736,135 +3767,66 @@ } // -- write sdx if playing live - bool usePlaybackPosition = (m_dwStatus & PATSTATUS_FOLLOWSONG) && // work out whether we should use - (pMainFrm->GetFollowSong(pModDoc) == m_hWnd) && // player engine position or - !(pSndFile->IsPaused()) && // edit cursor position - (CMainFrame::m_dwPatternSetup & PATTERN_AUTODELAY); + const bool usePlaybackPosition = (!bChordMode) && (bIsLiveRecord && (CMainFrame::m_dwPatternSetup & PATTERN_AUTODELAY)); //Work out where to put the note off - UINT nRow = usePlaybackPosition ? pSndFile->m_nRow : m_nRow; + ROWINDEX nRow = m_nRow; + PATTERNINDEX nPat = m_nPattern; - MODCOMMAND* p = pSndFile->Patterns[m_nPattern].GetpModCommand(nRow, (releaseChan < pSndFile->GetNumChannels()) ? releaseChan : nChn); + if(usePlaybackPosition) + SetEditPos(*pSndFile, nRow, nPat, nRowPlayback, nPatPlayback); + MODCOMMAND* p = pSndFile->Patterns[nPat].GetpModCommand(nRow, nChn); + //don't overwrite: - if (p->note || p->instr || p->volcmd) { + if (p->note || p->instr || p->volcmd) + { //if there's a note in the current location and the song is playing and following, //the user probably just tapped the key - let's try the next row down. - if (p->note==note && (m_dwStatus&PATSTATUS_FOLLOWSONG) && !(pSndFile->IsPaused())) { - p=pSndFile->Patterns[m_nPattern]+(nRow+1)*pSndFile->m_nChannels+releaseChan; - if (p->note || p->instr || p->volcmd) { + nRow++; + if (p->note==note && bIsLiveRecord && pSndFile->Patterns[nPat].IsValidRow(nRow)) + { + p = pSndFile->Patterns[nPat].GetpModCommand(nRow, nChn); + if (p->note || (!bChordMode && (p->instr || p->volcmd)) ) return; - } - } else { - return; } + else + return; } + // Create undo-point. + pModDoc->PrepareUndo(nPat, nChn, nRow, 1, 1); + // -- write sdx if playing live - if (usePlaybackPosition && pSndFile->m_nTickCount) { // avoid SD0 which will be mis-interpreted + if (usePlaybackPosition && nTick) { // avoid SD0 which will be mis-interpreted if (p->command == 0) { //make sure we don't overwrite any existing commands. - p->command = (pSndFile->m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT|MOD_TYPE_S3M))?CMD_S3MCMDEX:CMD_MODCMDEX; - p->param = 0xD0 + (pSndFile->m_nTickCount&0x0F); //&0x0F is to limit to max 0x0F + p->command = (pSndFile->TypeIsS3M_IT_MPT()) ? CMD_S3MCMDEX : CMD_MODCMDEX; + p->param = 0xD0 + min(0xF, nTick); } } //Enter note off - p->note = 0xFF; - p->instr = GetCurrentInstrument(); //p->instr = 0; + p->note = NOTE_KEYOFF; + p->instr = (bChordMode) ? 0 : GetCurrentInstrument(); //p->instr = 0; //Writing the instrument as well - probably someone finds this annoying :) p->volcmd = 0; p->vol = 0; pModDoc->SetModified(); - DWORD sel = (nRow << 16) | (releaseChan << 3); - InvalidateArea(sel, sel+5); - UpdateIndicator(); - return; - -} - -void CViewPattern::TempStopChord(int note) -//--------------------------------------------- -{ - CModDoc *pModDoc = GetDocument(); - CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); - bool isSplit = (note<m_nSplitNote); - if (pModDoc) + // Update only if not recording live. + if(bIsLiveRecord == false) { - UINT ins = 0; - if (isSplit) - { - ins = m_nSplitInstrument; - if (m_bOctaveLink) note += 12*(m_nOctaveModifier-9); - if (note > NOTE_MAX && note<254) note = NOTE_MAX; - if (note<0) note=1; - } - if (!ins) ins = GetCurrentInstrument(); - if (!ins) ins = m_nFoundInstrument; - - m_dwStatus &= ~PATSTATUS_CHORDPLAYING; - pModDoc->NoteOff(0, TRUE, ins, m_dwCursor & 0xFFFF); + DWORD sel = (nRow << 16) | (nChn << 3); + InvalidateArea(sel, sel+5); + UpdateIndicator(); } - //Enter note off in pattern? - if ((note < 1) || (note > NOTE_MAX)) - return; - if ((m_dwCursor & 7) > 1) - return; - //if (!pModDoc || !pMainFrm || !(m_dwStatus & PATSTATUS_RECORD)) - if (!pModDoc || !pMainFrm || !(IsEditingEnabled())) - return; - - CSoundFile *pSndFile = pModDoc->GetSoundFile(); - UINT nChn = GetChanFromCursor(m_dwCursor); - PrepareUndo(m_dwBeginSel, m_dwEndSel); - - BYTE* activeNoteMap = isSplit ? splitActiveNoteChannel : activeNoteChannel; - CHANNELINDEX releaseChan = activeNoteMap[note]; - if (releaseChan > pSndFile->GetNumChannels()) - releaseChan = nChn; - - activeNoteMap[note] = 0xFF; //unlock channel - - if (!(CMainFrame::m_dwPatternSetup&PATTERN_KBDNOTEOFF )) - return; - - MODCOMMAND* p = pSndFile->Patterns[m_nPattern].GetpModCommand(m_nRow, nChn); - - //don't overwrite: - if (p->note) - { - //if there's a note in the current location and the song is playing and following, - //the user probably just tapped the key - let's try the nex row down. - if (p->note==note && (m_dwStatus&PATSTATUS_FOLLOWSONG) && !(pSndFile->IsPaused())) - { - p=pSndFile->Patterns[m_nPattern]+(m_nRow+1)*pSndFile->m_nChannels+nChn; - if (p->note) - return; - } - else - { - return; - } - - } - - p->note = 0xFF; - p->instr = 0; - p->volcmd = 0; - p->vol = 0; - p->command = 0; - p->param = 0; - - pModDoc->SetModified(); - DWORD sel = (m_nRow << 16) | (releaseChan << 3); - InvalidateArea(sel, sel+5); - UpdateIndicator(); - return; + } + void CViewPattern::TempEnterOctave(int val) //--------------------------------------------- { @@ -3938,26 +3900,28 @@ { CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); CModDoc *pModDoc = GetDocument(); - bool isSplit; if ((pModDoc) && (pMainFrm)) { - UINT nRow = m_nRow; CSoundFile *pSndFile = pModDoc->GetSoundFile(); + const ROWINDEX nRowPlayback = pSndFile->m_nRow; + const UINT nTick = pSndFile->m_nTickCount; + const PATTERNINDEX nPatPlayback = pSndFile->m_nPattern; - UINT nChn = GetChanFromCursor(m_dwCursor); + const bool bRecordEnabled = IsEditingEnabled(); + const UINT nChn = GetChanFromCursor(m_dwCursor); BYTE recordGroup = pModDoc->IsChannelRecord(nChn); UINT nPlayIns = 0; - PrepareUndo(m_dwBeginSel, m_dwEndSel); + if (note > NOTE_MAX && note < 254) note = NOTE_MAX; - bool usePlaybackPosition = (m_dwStatus & PATSTATUS_FOLLOWSONG) && // work out whether we should use - (pMainFrm->GetFollowSong(pModDoc) == m_hWnd) && // player engine position or - !(pSndFile->IsPaused()) && // edit cursor position - (CMainFrame::m_dwPatternSetup & PATTERN_AUTODELAY); + const bool bIsLiveRecord = IsLiveRecord(*pMainFrm, *pModDoc, *pSndFile); + const bool usePlaybackPosition = (bIsLiveRecord && (CMainFrame::m_dwPatternSetup & PATTERN_AUTODELAY)); + ROWINDEX nRow = m_nRow; + // -- Chord autodetection: step back if we just entered a note - if ((IsEditingEnabled()) && (recordGroup) && !usePlaybackPosition) { + if ((bRecordEnabled) && (recordGroup) && !bIsLiveRecord) { if ((m_nSpacing > 0) && (m_nSpacing <= MAX_SPACING)) { if ((timeGetTime() - m_dwLastNoteEntryTime < CMainFrame::gnAutoChordWaitTime) && (nRow>=m_nSpacing) && (!m_bLastNoteEntryBlocked)) @@ -3966,17 +3930,24 @@ } m_dwLastNoteEntryTime = timeGetTime(); - nRow = usePlaybackPosition ? pSndFile->m_nRow : m_nRow; + PATTERNINDEX nPat = m_nPattern; + if(usePlaybackPosition) + SetEditPos(*pSndFile, nRow, nPat, nRowPlayback, nPatPlayback); + // -- Work out where to put the new note - MODCOMMAND* p = pSndFile->Patterns[m_nPattern].GetpModCommand(nRow, nChn); + MODCOMMAND* p = pSndFile->Patterns[nPat].GetpModCommand(nRow, nChn); //take backup copy of the command we're about to overwrite - MODCOMMAND oldcmd = *p; + const MODCOMMAND oldcmd = *p; - // -- write note and instrument data - isSplit = HandleSplit(p, note); + // If record is enabled, create undo point. + if(bRecordEnabled) + pModDoc->PrepareUndo(nPat, nChn, nRow, 1, 1); + // -- write note and instrument data. + const bool isSplit = HandleSplit(p, note); + // -- write vol data if (vol>=0 && vol<=64 && !(isSplit && m_nSplitVolume)) { //write valid volume, as long as there's no split volume override. p->volcmd=VOLCMD_VOLUME; @@ -3989,37 +3960,43 @@ } // -- write sdx if playing live - if (usePlaybackPosition && pSndFile->m_nTickCount) { // avoid SD0 which will be mis-interpreted + if (usePlaybackPosition && nTick) { // avoid SD0 which will be mis-interpreted if (p->command == 0) { //make sure we don't overwrite any existing commands. - p->command = (pSndFile->m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT|MOD_TYPE_S3M))?CMD_S3MCMDEX:CMD_MODCMDEX; - p->param = 0xD0 + (pSndFile->m_nTickCount&0x0F); //&0x0F is to limit to max 0x0F + p->command = (pSndFile->TypeIsS3M_IT_MPT()) ? CMD_S3MCMDEX : CMD_MODCMDEX; + p->param = 0xD0 + min(0xF, nTick); } } // -- old style note cut/off: erase instrument number - if (oldStyle && ((p->note==254) || (p->note==255))) { + if (oldStyle && ((p->note==NOTE_NOTECUT) || (p->note==NOTE_KEYOFF))) { p->instr=0; } - + // -- if recording, handle post note entry behaviour (move cursor etc..) - if(IsEditingEnabled()) + if(bRecordEnabled) { DWORD sel = (nRow << 16) | m_dwCursor; - SetCurSel(sel, sel); - sel &= ~7; + if(bIsLiveRecord == false) + { // Update only when not recording live. + SetCurSel(sel, sel); + sel &= ~7; + } + if(*p != oldcmd) //has it really changed? { pModDoc->SetModified(); - InvalidateArea(sel, sel+5); - UpdateIndicator(); + if(bIsLiveRecord == false) + { // Update only when not recording live. + InvalidateArea(sel, sel+5); + UpdateIndicator(); + } } - //Move cursor down if follow song off or song is paused - if ((pMainFrm->GetFollowSong(pModDoc) != m_hWnd) || (pSndFile->IsPaused()) - || (!(m_dwStatus & PATSTATUS_FOLLOWSONG))) + //Move cursor down only if not recording live. + if ( bIsLiveRecord == false ) { if ((m_nSpacing > 0) && (m_nSpacing <= MAX_SPACING)) { - if (nRow+m_nSpacing<pSndFile->PatternSize[m_nPattern]) { + if (nRow+m_nSpacing<pSndFile->PatternSize[nPat]) { SetCurrentRow(nRow+m_nSpacing); m_bLastNoteEntryBlocked=false; } else { @@ -4041,9 +4018,9 @@ bool channelLocked; UINT n = nChn; - for (UINT i=0; i<pSndFile->m_nChannels; i++) + for (UINT i=1; i<pSndFile->m_nChannels; i++) { - if (++n > pSndFile->m_nChannels) n = 0; //loop around + if (++n >= pSndFile->m_nChannels) n = 0; //loop around channelLocked = false; for (int k=0; k<NOTE_MAX; k++) @@ -4065,7 +4042,7 @@ } // -- play note - if ((CMainFrame::m_dwPatternSetup & PATTERN_PLAYNEWNOTE) || (!IsEditingEnabled())) + if ((CMainFrame::m_dwPatternSetup & PATTERN_PLAYNEWNOTE) || (bRecordEnabled == false)) { if (p->instr) nPlayIns = p->instr; @@ -4100,7 +4077,7 @@ } //-- if not recording, restore old command. - if (!(IsEditingEnabled())) + if (bRecordEnabled == false) { *p = oldcmd; } @@ -4932,5 +4909,19 @@ - - +void CViewPattern::SetEditPos(const CSoundFile& rSndFile, + ROWINDEX& iRow, PATTERNINDEX& iPat, + const ROWINDEX iRowCandidate, const PATTERNINDEX iPatCandidate) const +//------------------------------------------------------------------------------------------- +{ + if(rSndFile.Patterns.IsValidIndex(iPatCandidate) && rSndFile.Patterns[iPatCandidate].IsValidRow(iRowCandidate)) + { // Case: Edit position candidates are valid -- use them. + iPat = iPatCandidate; + iRow = iRowCandidate; + } + else // Case: Edit position candidates are not valid -- set edit cursor position instead. + { + iPat = m_nPattern; + iRow = m_nRow; + } +} Modified: trunk/OpenMPT/mptrack/View_pat.h =================================================================== --- trunk/OpenMPT/mptrack/View_pat.h 2009-01-04 10:29:46 UTC (rev 242) +++ trunk/OpenMPT/mptrack/View_pat.h 2009-01-10 07:52:25 UTC (rev 243) @@ -174,9 +174,9 @@ BOOL ExecuteCommand(CommandID command); void CursorJump(DWORD distance, bool direction, bool snap); void TempEnterNote(int n, bool oldStyle = false, int vol = -1); - void TempStopNote(int note, bool fromMidi=false); + void TempStopNote(int note, bool fromMidi=false, const bool bChordMode=false); void TempEnterChord(int n); - void TempStopChord(int note); + void TempStopChord(int note) {TempStopNote(note, false, true);} void TempEnterIns(int val); void TempEnterOctave(int val); void TempEnterVol(int v); @@ -324,7 +324,17 @@ bool IsInterpolationPossible(UINT startRow, UINT endRow, UINT chan, UINT colType, CSoundFile* pSndFile); void Interpolate(UINT type); - + // Return true if recording live (i.e. editing while following playback). + // rSndFile must be the CSoundFile object of given rModDoc. + bool IsLiveRecord(const CModDoc& rModDoc, const CSoundFile& rSndFile) const; + bool IsLiveRecord(const CMainFrame& rMainFrm, const CModDoc& rModDoc, const CSoundFile& rSndFile) const; + + // If given edit positions are valid, sets them to iRow and iPat. + // If not valid, set edit cursor position. + void SetEditPos(const CSoundFile& rSndFile, + ROWINDEX& iRow, PATTERNINDEX& iPat, + const ROWINDEX iRowCandidate, const PATTERNINDEX iPatCandidate) const; + bool IsEditingEnabled() const {return ((m_dwStatus&PATSTATUS_RECORD) != 0);} //Like IsEditingEnabled(), but shows some notification when editing is not enabled. @@ -344,6 +354,19 @@ }; +inline bool CViewPattern::IsLiveRecord(const CMainFrame& rMainFrm, const CModDoc& rModDoc, const CSoundFile& rSndFile) const +//---------------------------------------------------------------------------- +{ // (following song) && (following in correct document(?)) && (playback is on) + return ((m_dwStatus & PATSTATUS_FOLLOWSONG) && (rMainFrm.GetFollowSong(&rModDoc) == m_hWnd) && !(rSndFile.IsPaused())); +} + + +inline bool CViewPattern::IsLiveRecord(const CModDoc& rModDoc, const CSoundFile& rSndFile) const +//---------------------------------------------------------------------------- +{ + return IsLiveRecord(*CMainFrame::GetMainFrame(), rModDoc, rSndFile); +} + #endif Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2009-01-04 10:29:46 UTC (rev 242) +++ trunk/OpenMPT/mptrack/mptrack.rc 2009-01-10 07:52:25 UTC (rev 243) @@ -189,11 +189,13 @@ MENUITEM SEPARATOR POPUP "&Internet" BEGIN + MENUITEM "Modplug Central &Forums", ID_NETLINK_FORUMS MENUITEM "OpenMPT Wiki", ID_NETLINK_OPENMPTWIKI - MENUITEM "Modplug Central &Forums", ID_NETLINK_FORUMS + MENUITEM "OpenMPT Wiki (German)", ID_NETLINK_OPENMPTWIKI_GERMAN + MENUITEM "MPT-FR", ID_NETLINK_MPTFR MENUITEM "&Kvr Audio (plugins)", ID_NETLINK_PLUGINS - MENUITEM "&OSMusic.net", ID_NETLINK_TRAXINSPACE + MENUITEM "The Mod Archive", ID_NETLINK_MODARCHIVE END MENUITEM SEPARATOR MENUITEM "&About MPTrack...", ID_APP_ABOUT @@ -253,65 +255,65 @@ ES_READONLY | NOT WS_BORDER END -IDD_OPTIONS_PLAYER DIALOGEX 0, 0, 266, 278 +IDD_OPTIONS_PLAYER DIALOGEX 0, 0, 272, 279 STYLE DS_SETFONT | DS_3DLOOK | WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Player" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN - GROUPBOX "Sound Quality",IDC_STATIC,1,155,256,97 + GROUPBOX "Sound Quality",IDC_STATIC,5,165,256,97 CONTROL "Automatic Gain Control",IDC_CHECK2,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,9,20,97,10 + BS_AUTOCHECKBOX | WS_TABSTOP,15,20,97,10 CONTROL "Noise reduction",IDC_CHECK5,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,9,32,82,10 - LTEXT "Resampling:",IDC_STATIC,7,169,41,8 - COMBOBOX IDC_COMBO1,50,167,120,56,CBS_DROPDOWNLIST | WS_VSCROLL | + WS_TABSTOP,15,32,82,10 + LTEXT "Resampling:",IDC_STATIC,11,179,41,8 + COMBOBOX IDC_COMBO1,54,177,120,56,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "Bass Expansion",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,9,53,81,10 - LTEXT "Low",IDC_STATIC,12,67,14,8 + WS_TABSTOP,15,53,81,10 + LTEXT "Low",IDC_STATIC,17,67,14,8 CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH | - TBS_NOTICKS | WS_TABSTOP,27,65,62,15 - LTEXT "High",IDC_STATIC,90,67,16,8 - LTEXT "10Hz",IDC_STATIC,126,67,18,8 - LTEXT "Range:",IDC_STATIC,163,53,24,8 + TBS_NOTICKS | WS_TABSTOP,33,65,62,15 + LTEXT "High",IDC_STATIC,95,67,16,8 + LTEXT "10Hz",IDC_STATIC,131,67,18,8 + LTEXT "Range:",IDC_STATIC,169,53,24,8 CONTROL "Slider2",IDC_SLIDER2,"msctls_trackbar32",TBS_BOTH | - TBS_NOTICKS | WS_TABSTOP,143,64,62,15 - LTEXT "100Hz",IDC_STATIC,205,66,23,8 + TBS_NOTICKS | WS_TABSTOP,149,64,62,15 + LTEXT "100Hz",IDC_STATIC,211,66,23,8 CONTROL "Reverb",IDC_CHECK6,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,9,84,62,10 - LTEXT "Low",IDC_STATIC,12,100,14,8 + WS_TABSTOP,15,84,62,10 + LTEXT "Low",IDC_STATIC,17,100,14,8 CONTROL "Slider1",IDC_SLIDER3,"msctls_trackbar32",TBS_BOTH | - TBS_NOTICKS | WS_TABSTOP,27,96,62,15 - LTEXT "High",IDC_STATIC,90,100,16,8 - CTEXT "Reverb Preset:",IDC_STATIC,143,90,62,8 + TBS_NOTICKS | WS_TABSTOP,33,96,62,15 + LTEXT "High",IDC_STATIC,95,100,16,8 + CTEXT "Reverb Preset:",IDC_STATIC,149,90,62,8 CONTROL "Pro-Logic Surround",IDC_CHECK4,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,9,116,99,10 - LTEXT "Low",IDC_STATIC,12,132,14,8 + WS_TABSTOP,15,116,99,10 + LTEXT "Low",IDC_STATIC,17,132,14,8 CONTROL "Slider1",IDC_SLIDER5,"msctls_trackbar32",TBS_BOTH | - TBS_NOTICKS | WS_TABSTOP,27,129,62,15 - LTEXT "High",IDC_STATIC,90,132,16,8 - LTEXT "5ms",IDC_STATIC,126,131,18,8 - CTEXT "Front/Rear Delay:",IDC_STATIC,142,118,65,8 + TBS_NOTICKS | WS_TABSTOP,33,129,62,15 + LTEXT "High",IDC_STATIC,95,132,16,8 + LTEXT "5ms",IDC_STATIC,131,131,18,8 + CTEXT "Front/Rear Delay:",IDC_STATIC,147,118,65,8 CONTROL "Slider2",IDC_SLIDER6,"msctls_trackbar32",TBS_BOTH | - TBS_NOTICKS | WS_TABSTOP,143,128,62,15 - LTEXT "50ms",IDC_STATIC,205,131,23,8 - COMBOBOX IDC_COMBO2,130,97,100,100,CBS_DROPDOWNLIST | WS_VSCROLL | + TBS_NOTICKS | WS_TABSTOP,149,128,62,15 + LTEXT "50ms",IDC_STATIC,211,131,23,8 + COMBOBOX IDC_COMBO2,135,97,100,100,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - GROUPBOX "Control",IDC_STATIC,0,5,257,150 - EDITTEXT IDC_WFIRCUTOFF,150,205,19,14,ES_AUTOHSCROLL | ES_NUMBER - COMBOBOX IDC_WFIRTYPE,50,186,119,64,CBS_DROPDOWN | WS_VSCROLL | + GROUPBOX "Control",IDC_STATIC,5,5,257,150 + EDITTEXT IDC_WFIRCUTOFF,154,215,19,14,ES_AUTOHSCROLL | ES_NUMBER + COMBOBOX IDC_WFIRTYPE,54,196,119,64,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - LTEXT "WFIR type:",IDC_STATIC,7,188,37,8 - LTEXT "WFIR cutoff factor:",IDC_STATIC,8,208,62,8 - LTEXT "%",IDC_STATIC,173,208,8,8 - LTEXT "Sample ramping (click avoidance):",IDC_STATIC,8,228,109, - 8 - EDITTEXT IDC_RAMPING,145,225,24,14,ES_AUTOHSCROLL | ES_NUMBER - LTEXT "Samples",IDC_STATIC,172,228,29,8 - LTEXT "(can be overridden by instrument setting)",IDC_STATIC,9, - 238,128,8 + LTEXT "WFIR type:",IDC_STATIC,11,198,37,8 + LTEXT "WFIR cutoff factor:",IDC_STATIC,12,218,62,8 + LTEXT "%",IDC_STATIC,177,218,8,8 + LTEXT "Sample ramping (click avoidance):",IDC_STATIC,12,238, + 109,8 + EDITTEXT IDC_RAMPING,149,235,24,14,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "Samples",IDC_STATIC,176,238,29,8 + LTEXT "(can be overridden by instrument setting)",IDC_STATIC, + 13,248,128,8 CONTROL "Enable Graphic Equalizer",IDC_CHECK3,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,130,20,107,10 + BS_AUTOCHECKBOX | WS_TABSTOP,135,20,107,10 END IDD_WAVECONVERT DIALOGEX 0, 0, 211, 166 @@ -367,141 +369,142 @@ CTEXT "Writing file...",IDC_TEXT1,4,4,178,9 END -IDD_OPTIONS_KEYBOARD DIALOGEX 0, 0, 266, 278 +IDD_OPTIONS_KEYBOARD DIALOGEX 0, 0, 272, 279 STYLE DS_SETFONT | WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Keyboard" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN - COMBOBOX IDC_KEYCATEGORY,0,16,130,204,CBS_DROPDOWNLIST | + COMBOBOX IDC_KEYCATEGORY,5,16,130,204,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LISTBOX IDC_COMMAND_LIST,0,32,130,242,LBS_NOINTEGRALHEIGHT | + LISTBOX IDC_COMMAND_LIST,5,32,130,242,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_CHOICECOMBO,141,16,79,51,CBS_DROPDOWN | WS_VSCROLL | + COMBOBOX IDC_CHOICECOMBO,147,16,79,51,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - EDITTEXT IDC_CUSTHOTKEY,157,31,98,13,ES_AUTOHSCROLL + EDITTEXT IDC_CUSTHOTKEY,163,31,98,13,ES_AUTOHSCROLL CONTROL "On Key Down",IDC_CHECKKEYDOWN,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,141,44,66,14 + WS_TABSTOP,147,44,66,14 CONTROL "On Key Hold",IDC_CHECKKEYHOLD,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,141,57,66,10 + WS_TABSTOP,147,57,66,10 CONTROL "On Key Up",IDC_CHECKKEYUP,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,141,68,66,8 - PUSHBUTTON "Restore",IDC_RESTORE,212,46,43,13 - PUSHBUTTON "Delete",IDC_DELETE,212,64,43,13 - EDITTEXT IDC_KEYREPORT,135,94,125,70,ES_MULTILINE | + WS_TABSTOP,147,68,66,8 + PUSHBUTTON "Restore",IDC_RESTORE,217,46,43,13 + PUSHBUTTON "Delete",IDC_DELETE,217,64,43,13 + EDITTEXT IDC_KEYREPORT,141,94,125,70,ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_VSCROLL - PUSHBUTTON "Y",IDC_NOTESREPEAT,230,176,12,9 - PUSHBUTTON "N",IDC_NONOTESREPEAT,245,176,12,9 - EDITTEXT IDC_CHORDDETECTWAITTIME,229,189,28,12,ES_AUTOHSCROLL | + PUSHBUTTON "Y",IDC_NOTESREPEAT,235,176,12,9 + PUSHBUTTON "N",IDC_NONOTESREPEAT,251,176,12,9 + EDITTEXT IDC_CHORDDETECTWAITTIME,235,189,28,12,ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT - PUSHBUTTON "it",IDC_EFFECTLETTERSIT,98,184,12,9,NOT WS_VISIBLE - PUSHBUTTON "xm",IDC_EFFECTLETTERSXM,113,184,12,9,NOT WS_VISIBLE - PUSHBUTTON "Load Keys...",IDC_LOAD,139,221,54,13 - PUSHBUTTON "Save Keys As...",IDC_SAVE,199,221,54,13 + PUSHBUTTON "it",IDC_EFFECTLETTERSIT,103,184,12,9,NOT WS_VISIBLE + PUSHBUTTON "xm",IDC_EFFECTLETTERSXM,119,184,12,9,NOT WS_VISIBLE + PUSHBUTTON "Load Keys...",IDC_LOAD,145,221,54,13 + PUSHBUTTON "Save Keys As...",IDC_SAVE,205,221,54,13 CONTROL "Debug Save",IDC_DEBUGSAVE,"Button",BS_AUTOCHECKBOX | - NOT WS_VISIBLE | WS_TABSTOP,53,199,56,10 - EDITTEXT IDC_KEYMAPFILE,139,249,114,13,ES_AUTOHSCROLL - LTEXT "Select category:",IDC_STATIC,1,5,74,11 - PUSHBUTTON "Set",IDC_SET,222,46,43,13,NOT WS_VISIBLE - GROUPBOX "Key setup for this command ",IDC_STATIC,134,5,127,75 - LTEXT "Key:",IDC_STATIC,141,33,16,8 - GROUPBOX "Misc",IDC_STATIC,134,167,126,40 - GROUPBOX "Multi Config Handling",IDC_STATIC,134,209,126,66 - LTEXT "Repeat notes on hold?",IDC_STATIC,138,176,74,11 - LTEXT "Effect letters like:",IDC_STATIC,6,185,73,11,NOT + NOT WS_VISIBLE | WS_TABSTOP,59,199,56,10 + EDITTEXT IDC_KEYMAPFILE,145,249,114,13,ES_AUTOHSCROLL + LTEXT "Select category:",IDC_STATIC,7,5,74,11 + PUSHBUTTON "Set",IDC_SET,225,45,43,13,NOT WS_VISIBLE + GROUPBOX "Key setup for this command ",IDC_STATIC,139,5,127,75 + LTEXT "Key:",IDC_STATIC,147,33,16,8 + GROUPBOX "Misc",IDC_STATIC,139,167,126,40 + GROUPBOX "Multi Config Handling",IDC_STATIC,139,209,126,66 + LTEXT "Repeat notes on hold?",IDC_STATIC,143,176,74,11 + LTEXT "Effect letters like:",IDC_STATIC,11,185,73,11,NOT WS_VISIBLE - LTEXT "Chord detect interval (ms):",IDC_STATIC,138,190,88,11 + LTEXT "Chord detect interval (ms):",IDC_STATIC,143,190,88,11 CONTROL "Save to this file on OK/Apply?",IDC_AUTOSAVE,"Button", - BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,147,262,106, + BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,153,262,106, 10 - LTEXT "Config to load on startup:",IDC_STATIC,139,239,80,8 - LTEXT "Log:",IDC_STATIC,136,84,19,10 - PUSHBUTTON "Clear Log",IDC_CLEARLOG,222,85,37,9 + LTEXT "Config to load on startup:",IDC_STATIC,145,239,80,8 + LTEXT "Log:",IDC_STATIC,141,84,19,10 + PUSHBUTTON "Clear Log",IDC_CLEARLOG,227,85,37,9 END -IDD_OPTIONS_COLORS DIALOGEX 0, 0, 265, 278 +IDD_OPTIONS_COLORS DIALOGEX 0, 0, 272, 231 STYLE DS_SETFONT | DS_3DLOOK | WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Colors" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN - COMBOBOX IDC_COMBO1,9,26,134,109,CBS_DROPDOWNLIST | WS_VSCROLL | + COMBOBOX IDC_COMBO1,15,25,134,109,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "Primary highlight",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,19,75,74,10 - EDITTEXT IDC_PRIMARYHILITE,100,74,21,12,ES_AUTOHSCROLL | + WS_TABSTOP,20,91,74,10 + EDITTEXT IDC_PRIMARYHILITE,101,90,21,12,ES_AUTOHSCROLL | ES_NUMBER CONTROL "Secondary highlight",IDC_CHECK4,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,19,87,80,10 - EDITTEXT IDC_SECONDARYHILITE,100,86,21,12,ES_AUTOHSCROLL | + BS_AUTOCHECKBOX | WS_TABSTOP,20,103,80,10 + EDITTEXT IDC_SECONDARYHILITE,101,102,21,12,ES_AUTOHSCROLL | ES_NUMBER CONTROL "Enable effect highlighting",IDC_CHECK2,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,10,53,114,10 + BS_AUTOCHECKBOX | WS_TABSTOP,15,60,114,10 CONTROL "Use small font",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,10,43,102,10 - PUSHBUTTON "MPT",IDC_BUTTON5,154,26,22,12 - PUSHBUTTON "FT2",IDC_BUTTON6,179,26,22,12 - PUSHBUTTON "IT",IDC_BUTTON7,154,40,22,12 - PUSHBUTTON "Buzz",IDC_BUTTON8,179,40,22,12 - CONTROL "Color",IDC_BUTTON1,"Button",BS_OWNERDRAW,15,174,51,15 - CONTROL "Color",IDC_BUTTON2,"Button",BS_OWNERDRAW,88,174,51,15 - CONTROL "Color",IDC_BUTTON3,"Button",BS_OWNERDRAW,158,174,51,15 - LTEXT "Background:",IDC_TEXT1,15,163,60,8 - LTEXT "Foreground:",IDC_TEXT2,88,163,62,8 - LTEXT "Highlight:",IDC_TEXT3,159,164,61,8 - GROUPBOX "",IDC_STATIC,4,7,217,191 - LTEXT "Select color for:",IDC_STATIC,10,15,63,8 - LTEXT "rows",IDC_STATIC,124,76,16,8 - LTEXT "Presets:",IDC_STATIC,154,15,28,8 - LTEXT "rows",IDC_STATIC,124,88,16,8 - CONTROL "",IDC_BUTTON4,"Button",BS_OWNERDRAW | BS_FLAT,54,113, + WS_TABSTOP,15,45,102,10 + PUSHBUTTON "MPT",IDC_BUTTON5,159,26,22,12 + PUSHBUTTON "FT2",IDC_BUTTON6,185,26,22,12 + PUSHBUTTON "IT",IDC_BUTTON7,210,25,22,12 + PUSHBUTTON "Buzz",IDC_BUTTON8,235,25,22,12 + CONTROL "Color",IDC_BUTTON1,"Button",BS_OWNERDRAW,25,194,51,15 + CONTROL "Color",IDC_BUTTON2,"Button",BS_OWNERDRAW,98,194,51,15 + CONTROL "Color",IDC_BUTTON3,"Button",BS_OWNERDRAW,168,194,51,15 + LTEXT "Background:",IDC_TEXT1,25,183,60,8 + LTEXT "Foreground:",IDC_TEXT2,98,183,62,8 + LTEXT "Highlight:",IDC_TEXT3,169,185,61,8 + GROUPBOX "",IDC_STATIC,5,5,260,220 + LTEXT "Select color for:",IDC_STATIC,15,15,63,8 + LTEXT "rows",IDC_STATIC,125,92,16,8 + LTEXT "Presets:",IDC_STATIC,159,15,28,8 + LTEXT "rows",IDC_STATIC,125,104,16,8 + CONTROL "",IDC_BUTTON4,"Button",BS_OWNERDRAW | BS_FLAT,65,130, 114,43 CONTROL "Set highlights to songs' time signatures",IDC_CHECK5, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,63,136,10 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,75,136,10 END -IDD_MIDISETUP DIALOGEX 0, 0, 240, 191 +IDD_MIDISETUP DIALOGEX 0, 0, 272, 281 STYLE DS_SETFONT | DS_3DLOOK | WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Midi" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN - GROUPBOX "",IDC_STATIC,5,14,235,174 - LTEXT "Midi Input Device:",IDC_STATIC,13,14,67,8 - COMBOBOX IDC_COMBO1,13,24,144,74,CBS_DROPDOWNLIST | WS_VSCROLL | + GROUPBOX "Midi Recording",IDC_STATIC,5,5,260,185 + LTEXT "Midi Input Device:",IDC_STATIC,15,20,67,8 + COMBOBOX IDC_COMBO1,15,30,120,74,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Midi Output Device:",IDC_STATIC,13,42,65,8,NOT + LTEXT "Midi Output Device:",IDC_STATIC,140,20,65,8,NOT WS_VISIBLE - COMBOBOX IDC_COMBO2,13,54,144,73,CBS_DROPDOWNLIST | NOT + COMBOBOX IDC_COMBO2,140,30,120,73,CBS_DROPDOWNLIST | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP - CONTROL "Transpose external midi keyboard",IDC_CHECK4,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,11,82,126,9 + CONTROL "Apply Octave Transpose on external midi keyboard", + IDC_CHECK4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,55, + 185,9 CONTROL "Amplify Midi Velocity",IDC_CHECK3,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,11,93,113,9 + BS_AUTOCHECKBOX | WS_TABSTOP,15,90,113,9 CONTROL "Record note velocity",IDC_CHECK1,"Button", - BS_AUTOCHECKBOX | BS_TOP | WS_TABSTOP,11,104,132,9 + BS_AUTOCHECKBOX | BS_TOP | WS_TABSTOP,15,75,132,9 CONTROL "Record Note Off (Instruments Only)",IDC_CHECK2,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,11,126,130,9 - GROUPBOX "File import",IDC_STATIC,176,14,53,74 - LTEXT "Speed:",IDC_STATIC,183,26,24,8 - EDITTEXT IDC_EDIT1,183,37,39,12,ES_AUTOHSCROLL | ES_NUMBER + BS_AUTOCHECKBOX | WS_TABSTOP,15,120,130,9 + GROUPBOX "Midi file import",IDC_STATIC,5,200,260,45 + LTEXT "Speed:",IDC_STATIC,15,220,24,8 + EDITTEXT IDC_EDIT1,45,220,39,12,ES_AUTOHSCROLL | ES_NUMBER CONTROL "Spin1",IDC_SPIN1,"msctls_updown32",UDS_SETBUDDYINT | - UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,217,42, + UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,79,225, 11,14 - LTEXT "Pattern size:",IDC_STATIC,183,58,40,8 - EDITTEXT IDC_EDIT2,183,69,39,12,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "Pattern size:",IDC_STATIC,115,220,40,8 + EDITTEXT IDC_EDIT2,165,220,39,12,ES_AUTOHSCROLL | ES_NUMBER CONTROL "Spin1",IDC_SPIN2,"msctls_updown32",UDS_SETBUDDYINT | - UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,214,71, + UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,196,222, 11,14 CONTROL "Pass MIDI to active instrument plugin (experimental)", IDC_MIDI_TO_PLUGIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 11,148,222,9 + 15,155,222,9 CONTROL "Combine midi volume to note velocity", IDC_MIDIVOL_TO_NOTEVOL,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,11,115,139,9 + WS_TABSTOP,15,105,139,9 CONTROL "Respond to play/continue/stop song messages (untested)", IDC_MIDIPLAYCONTROL,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,11,172,202,9 + WS_TABSTOP,15,170,202,9 CONTROL "Record MIDI controller changes as MIDI macro changes (in pattern)", IDC_MIDI_MACRO_CONTROL,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,11,160,226,9 + WS_TABSTOP,15,140,226,9 END IDD_LOADRAWSAMPLE DIALOG 0, 0, 168, 84 @@ -1403,72 +1406,72 @@ WS_TABSTOP,WS_EX_STATICEDGE END -IDD_OPTIONS_GENERAL DIALOGEX 0, 0, 265, 278 +IDD_OPTIONS_GENERAL DIALOGEX 0, 0, 272, 279 STYLE DS_SETFONT | DS_3DLOOK | WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "General" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN - GROUPBOX "Directories",IDC_STATIC,4,3,248,67 - LTEXT "Songs:",IDC_STATIC,11,17,36,12,SS_CENTERIMAGE - EDITTEXT IDC_EDIT1,55,17,174,12,ES_AUTOHSCROLL - PUSHBUTTON "...",IDC_BUTTON1,234,18,12,11,NOT WS_TABSTOP - LTEXT "Samples:",IDC_STATIC,11,34,41,12,SS_CENTERIMAGE - EDITTEXT IDC_EDIT2,55,34,174,12,ES_AUTOHSCROLL - PUSHBUTTON "...",IDC_BUTTON2,234,34,12,11,NOT WS_TABSTOP - LTEXT "Instruments:",IDC_STATIC,11,50,40,12,SS_CENTERIMAGE - EDITTEXT IDC_EDIT3,55,50,174,12,ES_AUTOHSCROLL - PUSHBUTTON "...",IDC_BUTTON3,234,51,12,11,NOT WS_TABSTOP - GROUPBOX "Options",IDC_STATIC,4,75,247,200 - LTEXT "Description",IDC_TEXT1,144,86,101,175 + GROUPBOX "Directories",IDC_STATIC,5,5,261,67 + LTEXT "Songs:",IDC_STATIC,15,20,36,12,SS_CENTERIMAGE + EDITTEXT IDC_EDIT1,59,20,174,12,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_BUTTON1,240,20,12,11,NOT WS_TABSTOP + LTEXT "Samples:",IDC_STATIC,15,37,41,12,SS_CENTERIMAGE + EDITTEXT IDC_EDIT2,59,37,174,12,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_BUTTON2,240,36,12,11,NOT WS_TABSTOP + LTEXT "Instruments:",IDC_STATIC,15,53,40,12,SS_CENTERIMAGE + EDITTEXT IDC_EDIT3,59,53,174,12,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_BUTTON3,240,54,12,11,NOT WS_TABSTOP + GROUPBOX "Options",IDC_STATIC,4,75,261,200 + LTEXT "Description",IDC_TEXT1,144,86,111,175 LISTBOX IDC_LIST1,9,86,129,181,LBS_OWNERDRAWFIXED | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP END -IDD_OPTIONS_SOUNDCARD DIALOGEX 0, 0, 266, 274 +IDD_OPTIONS_SOUNDCARD DIALOGEX 0, 0, 272, 276 STYLE DS_SETFONT | DS_3DLOOK | WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Sound Card" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN - GROUPBOX "",IDC_STATIC,4,3,232,167 - LTEXT "Sound Device:",IDC_STATIC,9,12,79,8 + GROUPBOX "",IDC_STATIC,5,5,232,170 + LTEXT "Sound Device:",IDC_STATIC,11,14,79,8 CONTROL "",IDC_COMBO1,"ComboBoxEx32",CBS_DROPDOWNLIST | CBS_SORT | - WS_VSCROLL | WS_TABSTOP,10,23,219,96 - LTEXT "Buffer length:",IDC_STATIC,11,44,43,8 - COMBOBOX IDC_COMBO2,71,41,54,83,CBS_DROPDOWN | WS_VSCROLL | + WS_VSCROLL | WS_TABSTOP,11,25,219,96 + LTEXT "Buffer length:",IDC_STATIC,13,46,43,8 + COMBOBOX IDC_COMBO2,73,43,54,83,CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP - LTEXT "Mixing Quality:",IDC_STATIC,11,62,57,8 - COMBOBOX IDC_COMBO3,71,60,54,90,CBS_DROPDOWNLIST | WS_VSCROLL | + LTEXT "Mixing Quality:",IDC_STATIC,13,64,57,8 + COMBOBOX IDC_COMBO3,73,62,54,90,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Max. Polyphony:",IDC_STATIC,11,78,57,8 - COMBOBOX IDC_COMBO4,71,76,54,88,CBS_DROPDOWNLIST | WS_TABSTOP + LTEXT "Max. Polyphony:",IDC_STATIC,13,80,57,8 + COMBOBOX IDC_COMBO4,73,78,54,88,CBS_DROPDOWNLIST | WS_TABSTOP CONTROL "Enable MMX Acceleration",IDC_CHECK3,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,11,95,112,10 + BS_AUTOCHECKBOX | WS_TABSTOP,13,97,112,10 CONTROL "Use secondary buffers",IDC_CHECK4,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,131,43,99,10 - LTEXT "Stereo Separation:",IDC_STATIC,25,112,62,8 - LTEXT "100%",IDC_TEXT1,93,112,20,8 - RTEXT "Low",IDC_STATIC,35,127,15,8 + BS_AUTOCHECKBOX | WS_TABSTOP,133,45,99,10 + LTEXT "Stereo Separation:",IDC_STATIC,27,114,62,8 + LTEXT "100%",IDC_TEXT1,95,114,20,8 + RTEXT "Low",IDC_STATIC,37,129,15,8 CONTROL "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_AUTOTICKS | - WS_TABSTOP,57,124,83,18 - LTEXT "High",IDC_STATIC,147,127,16,8 - CTEXT "Pre-Amp",IDC_STATIC,196,76,35,8 + WS_TABSTOP,59,126,83,18 + LTEXT "High",IDC_STATIC,149,129,16,8 + CTEXT "Pre-Amp",IDC_STATIC,197,78,35,8 CONTROL "Slider2",IDC_SLIDER_PREAMP,"msctls_trackbar32", - TBS_AUTOTICKS | TBS_VERT | TBS_BOTH | WS_TABSTOP,200,87, + TBS_AUTOTICKS | TBS_VERT | TBS_BOTH | WS_TABSTOP,201,89, 27,62 - COMBOBOX IDC_COMBO5,131,60,64,80,CBS_DROPDOWNLIST | WS_VSCROLL | + COMBOBOX IDC_COMBO5,133,62,64,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "Reverse Stereo",IDC_CHECK1,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,131,78,62,10 + WS_TABSTOP,133,80,62,10 CONTROL "Soft Panning",IDC_CHECK2,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,131,90,64,10 + WS_TABSTOP,133,92,64,10 LTEXT "Note: The Pre-Amp and Soft Panning settings are ignored by songs with mix levels set to 1.17RC3 or later in Song Properties.", - IDC_STATIC,16,150,204,18 + IDC_STATIC,17,152,204,18 END IDD_MIDIMACRO DIALOGEX 0, 0, 349, 345 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -EXSTYLE WS_EX_TOOLWINDOW | WS_EX_CLIENTEDGE +EXSTYLE WS_EX_TOOLWINDOW CAPTION "Zxx Macros Configuration" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN @@ -1781,35 +1784,35 @@ LTEXT "New:",IDC_STATIC,101,35,18,8 END -IDD_OPTIONS_AUTOSAVE DIALOGEX 0, 0, 265, 278 +IDD_OPTIONS_AUTOSAVE DIALOGEX 0, 0, 272, 279 STYLE DS_SETFONT | DS_3DLOOK | WS_CHILD | WS_DISABLED | WS_CAPTION CAPTION "Auto Save" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN CONTROL "Enable Autosave",IDC_AUTOSAVE_ENABLE,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,11,15,70,10 - EDITTEXT IDC_AUTOSAVE_INTERVAL,55,29,24,12,ES_AUTOHSCROLL | + BS_AUTOCHECKBOX | WS_TABSTOP,15,15,70,10 + EDITTEXT IDC_AUTOSAVE_INTERVAL,59,29,24,12,ES_AUTOHSCROLL | ES_NUMBER - EDITTEXT IDC_AUTOSAVE_HISTORY,55,46,24,12,ES_AUTOHSCROLL | + EDITTEXT IDC_AUTOSAVE_HISTORY,59,46,24,12,ES_AUTOHSCROLL | ES_NUMBER - EDITTEXT IDC_AUTOSAVE_PATH,56,91,164,12,ES_AUTOHSCROLL - PUSHBUTTON "...",IDC_AUTOSAVE_BROWSE,222,92,12,11,NOT WS_TABSTOP + EDITTEXT IDC_AUTOSAVE_PATH,60,96,164,12,ES_AUTOHSCROLL + PUSHBUTTON "...",IDC_AUTOSAVE_BROWSE,226,97,12,11,NOT WS_TABSTOP LTEXT "[filename].AutoSave.[timestamp].[extension]",IDC_STATIC, - 56,115,164,12,SS_CENTERIMAGE,WS_EX_CLIENTEDGE - GROUPBOX "Auto Save",IDC_STATIC,4,3,248,150 - LTEXT "Save every:",IDC_STATIC,11,29,40,12,SS_CENTERIMAGE - LTEXT "minutes",IDC_STATIC,83,29,36,12,SS_CENTERIMAGE - LTEXT "Filename:",IDC_STATIC,24,115,30,12,SS_CENTERIMAGE + 60,120,164,12,SS_CENTERIMAGE,WS_EX_CLIENTEDGE + GROUPBOX "Auto Save",IDC_STATIC,4,3,261,157 + LTEXT "Save every:",IDC_STATIC,15,29,40,12,SS_CENTERIMAGE + LTEXT "minutes",IDC_STATIC,87,29,36,12,SS_CENTERIMAGE + LTEXT "Filename:",IDC_STATIC,28,120,30,12,SS_CENTERIMAGE LTEXT "(example: mySong.AutoSave.20050327.2343.it)",IDC_STATIC, - 56,130,157,12,SS_CENTERIMAGE - LTEXT "Keep up to:",IDC_STATIC,11,46,36,12,SS_CENTERIMAGE - LTEXT "backups of each file name",IDC_STATIC,83,46,87,12, + 60,135,157,12,SS_CENTERIMAGE + LTEXT "Keep up to:",IDC_STATIC,15,46,36,12,SS_CENTERIMAGE + LTEXT "backups of each file name",IDC_STATIC,87,46,87,12, SS_CENTERIMAGE - GROUPBOX "Location:",IDC_STATIC,11,65,228,80 + GROUPBOX "Location:",IDC_STATIC,15,70,240,80 CONTROL "Use:",IDC_AUTOSAVE_USECUSTOMDIR,"Button", - BS_AUTORADIOBUTTON,24,92,31,10 + BS_AUTORADIOBUTTON,28,97,31,10 CONTROL "Use song's original directory.",IDC_AUTOSAVE_USEORIGDIR, - "Button",BS_AUTORADIOBUTTON,24,78,105,10 + "Button",BS_AUTORADIOBUTTON,28,83,105,10 END IDD_EDIT_GOTO DIALOGEX 0, 0, 129, 89 @@ -1968,9 +1971,11 @@ IDD_OPTIONS_PLAYER, DIALOG BEGIN + RIGHTMARGIN, 266 VERTGUIDE, 50 VERTGUIDE, 169 VERTGUIDE, 256 + BOTTOMMARGIN, 278 END IDD_WAVECONVERT, DIALOG @@ -1980,20 +1985,21 @@ IDD_OPTIONS_KEYBOARD, DIALOG BEGIN - RIGHTMARGIN, 260 + RIGHTMARGIN, 266 TOPMARGIN, 5 - BOTTOMMARGIN, 274 + BOTTOMMARGIN, 275 END IDD_OPTIONS_COLORS, DIALOG BEGIN - RIGHTMARGIN, 240 - BOTTOMMARGIN, 198 + RIGHTMARGIN, 247 + BOTTOMMARGIN, 151 END IDD_MIDISETUP, DIALOG BEGIN - BOTTOMMARGIN, 188 + RIGHTMARGIN, 240 + BOTTOMMARGIN, 278 END IDD_CONTROL_COMMENTS, DIALOG @@ -2074,14 +2080,14 @@ IDD_OPTIONS_GENERAL, DIALOG BEGIN - RIGHTMARGIN, 259 - BOTTOMMARGIN, 275 + RIGHTMARGIN, 266 + BOTTOMMARGIN, 276 END IDD_OPTIONS_SOUNDCARD, DIALOG BEGIN - RIGHTMARGIN, 240 - BOTTOMMARGIN, 177 + RIGHTMARGIN, 246 + BOTTOMMARGIN, 179 END IDD_MIDIMACRO, DIALOG @@ -2160,8 +2166,8 @@ IDD_OPTIONS_AUTOSAVE, DIALOG BEGIN - RIGHTMARGIN, 259 - BOTTOMMARGIN, 275 + RIGHTMARGIN, 266 + BOTTOMMARGIN, 276 END IDD_EDIT_GOTO, DIALOG Modified: trunk/OpenMPT/mptrack/pattern.h =================================================================== --- trunk/OpenMPT/mptrack/pattern.h 2009-01-04 10:29:46 UTC (rev 242) +++ trunk/OpenMPT/mptrack/pattern.h 2009-01-10 07:52:25 UTC (rev 243) @@ -36,6 +36,9 @@ ROWINDEX GetNumRows() const {return m_Rows;} + // Return true if modcommand can be accessed from given row, false otherwise. + bool IsValidRow(const ROWINDEX iRow) const {return (iRow < GetNumRows());} + CHANNELINDEX GetNumChannels() const; bool Resize(const ROWINDEX newRowCount, const bool showDataLossWarning = true); Modified: trunk/OpenMPT/mptrack/patternContainer.h =================================================================== --- trunk/OpenMPT/mptrack/patternContainer.h 2009-01-04 10:29:46 UTC (rev 242) +++ trunk/OpenMPT/mptrack/patternContainer.h 2009-01-10 07:52:25 UTC (rev 243) @@ -51,6 +51,9 @@ //Returns the index of given pattern, Size() if not found. PATTERNINDEX GetIndex(const MODPATTERN* const pPat) const; + + // Return true if pattern can be accessed with operator[](iPat), false otherwise. + bool IsValidIndex(const PATTERNINDEX iPat) const {return (iPat < Size());} void ResizeArray(const PATTERNINDEX newSize); Modified: trunk/OpenMPT/mptrack/resource.h =================================================================== --- trunk/OpenMPT/mptrack/resource.h 2009-01-04 10:29:46 UTC (rev 242) +++ trunk/OpenMPT/mptrack/resource.h 2009-01-10 07:52:25 UTC (rev 243) @@ -931,7 +931,6 @@ #define ID_PATTERNPASTE 32875 #define ID_NETLINK_MODPLUG 32876 #define ID_NETLINK_UT 32877 -#define ID_NETLINK_TRAXINSPACE 32878 #define ID_NETLINK_OSMUSIC 32878 #define ID_NETLINK_HANDBOOK 32879 #define ID_SAMPLE_TRIM 32880 @@ -1047,6 +1046,8 @@ #define ID_ENVELOPE_SCALEPOINTS 59208 #define ID_NETLINK_OPENMPTWIKI 59210 #define ID_VIEW_MIDIMAPPING 59211 +#define ID_NETLINK_OPENMPTWIKI_GERMAN 59213 +#define ID_NETLINK_MODARCHIVE 59214 // Next default values for new objects // @@ -1054,7 +1055,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 516 -#define _APS_NEXT_COMMAND_VALUE 59212 +#define _APS_NEXT_COMMAND_VALUE 59215 #define _APS_NEXT_CONTROL_VALUE 2340 #define _APS_NEXT_SYMED_VALUE 901 #endif Modified: trunk/OpenMPT/soundlib/midi.h =================================================================== --- trunk/OpenMPT/soundlib/midi.h 2009-01-04 10:29:46 UTC (rev 242) +++ trunk/OpenMPT/soundlib/midi.h 2009-01-10 07:52:25 UTC (rev 243) @@ -20,6 +20,7 @@ MIDIEVENT_NOTEON = 0x9, MIDIEVENT_CONTROLLERCHANGE = 0xB, MIDIEVENT_PITCHBEND = 0xE, + MIDISTATUS_ACTIVESENSING = 0xFE }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2009-01-12 20:03:35
|
Revision: 245 http://modplug.svn.sourceforge.net/modplug/?rev=245&view=rev Author: relabsoluness Date: 2009-01-12 20:03:26 +0000 (Mon, 12 Jan 2009) Log Message: ----------- ? Added NO_VST option to make build possible without VST SDK (and VST support); see Stdafx.h. Modified Paths: -------------- trunk/OpenMPT/mptrack/AbstractVstEditor.cpp trunk/OpenMPT/mptrack/AbstractVstEditor.h trunk/OpenMPT/mptrack/DefaultVstEditor.cpp trunk/OpenMPT/mptrack/DefaultVstEditor.h trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Stdafx.h trunk/OpenMPT/mptrack/VSTEditor.cpp trunk/OpenMPT/mptrack/VSTEditor.h trunk/OpenMPT/mptrack/View_gen.cpp trunk/OpenMPT/mptrack/Vstplug.cpp trunk/OpenMPT/mptrack/Vstplug.h trunk/OpenMPT/soundlib/Sndfile.cpp Modified: trunk/OpenMPT/mptrack/AbstractVstEditor.cpp =================================================================== --- trunk/OpenMPT/mptrack/AbstractVstEditor.cpp 2009-01-10 11:10:49 UTC (rev 244) +++ trunk/OpenMPT/mptrack/AbstractVstEditor.cpp 2009-01-12 20:03:26 UTC (rev 245) @@ -10,6 +10,7 @@ #include "dlg_misc.h" #include "AbstractVstEditor.h" +#ifndef NO_VST static void CreateVerifiedProgramName(const char* rawname, const size_t rnSize, char* name, const size_t nSize, @@ -701,4 +702,7 @@ int CAbstractVstEditor::GetLearnMacro() { return m_nLearnMacro; -} \ No newline at end of file +} + +#endif // NO_VST + Modified: trunk/OpenMPT/mptrack/AbstractVstEditor.h =================================================================== --- trunk/OpenMPT/mptrack/AbstractVstEditor.h 2009-01-10 11:10:49 UTC (rev 244) +++ trunk/OpenMPT/mptrack/AbstractVstEditor.h 2009-01-12 20:03:26 UTC (rev 245) @@ -1,6 +1,8 @@ //rewbs.defaultPlugGUI #pragma once +#ifndef NO_VST + class CAbstractVstEditor: public CDialog { @@ -70,4 +72,8 @@ afx_msg void OnInitMenu(CMenu* pMenu); void PrepareToLearnMacro(UINT nID); }; -//end rewbs.defaultPlugGUI \ No newline at end of file +//end rewbs.defaultPlugGUI + +#endif // NO_VST + + Modified: trunk/OpenMPT/mptrack/DefaultVstEditor.cpp =================================================================== --- trunk/OpenMPT/mptrack/DefaultVstEditor.cpp 2009-01-10 11:10:49 UTC (rev 244) +++ trunk/OpenMPT/mptrack/DefaultVstEditor.cpp 2009-01-12 20:03:26 UTC (rev 245) @@ -4,6 +4,8 @@ #include "defaultvsteditor.h" #include ".\defaultvsteditor.h" +#ifndef NO_VST + CDefaultVstEditor::CDefaultVstEditor(CVstPlugin *pPlugin) : CAbstractVstEditor(pPlugin) //------------------------------------------------------------------------------------- { @@ -186,3 +188,5 @@ } +#endif // NO_VST + Modified: trunk/OpenMPT/mptrack/DefaultVstEditor.h =================================================================== --- trunk/OpenMPT/mptrack/DefaultVstEditor.h 2009-01-10 11:10:49 UTC (rev 244) +++ trunk/OpenMPT/mptrack/DefaultVstEditor.h 2009-01-12 20:03:26 UTC (rev 245) @@ -8,6 +8,8 @@ PARAM_RESOLUTION=1000, }; +#ifndef NO_VST + class CDefaultVstEditor : public CAbstractVstEditor { @@ -45,3 +47,6 @@ void UpdateParamDisplays(); }; + +#endif // NO_VST + Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2009-01-10 11:10:49 UTC (rev 244) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2009-01-12 20:03:26 UTC (rev 245) @@ -625,10 +625,16 @@ //Adding version number to the frame title CString title = GetTitle(); + title += CString(" ") + MptVersion::str; #ifdef DEBUG title += CString(" DEBUG"); #endif - title += CString(" ") + MptVersion::str; + #ifdef NO_VST + title += " NO_VST"; + #endif + #ifdef NO_ASIO + title += " NO_ASIO"; + #endif SetTitle(title); OnUpdateFrameTitle(false); @@ -2322,6 +2328,7 @@ void CMainFrame::OnPluginManager() //-------------------------------- { +#ifndef NO_VST int nPlugslot=-1; CModDoc* pModDoc = GetActiveDoc(); @@ -2345,6 +2352,7 @@ CChildFrame *pActiveChild = (CChildFrame *)MDIGetActive(); pActiveChild->ForceRefresh(); } +#endif // NO_VST } // -! NEW_FEATURE#0002 @@ -2951,6 +2959,7 @@ void AddPluginNamesToCombobox(CComboBox& CBox, SNDMIXPLUGIN* plugarray, const bool librarynames) //--------------------------------------------------------------------- { +#ifndef NO_VST for (UINT iPlug=0; iPlug<MAX_MIXPLUGINS; iPlug++) { PSNDMIXPLUGIN p = &plugarray[iPlug]; @@ -2963,6 +2972,7 @@ CBox.AddString(str); } +#endif // NO_VST } void AddPluginParameternamesToCombobox(CComboBox& CBox, SNDMIXPLUGIN& plug) Modified: trunk/OpenMPT/mptrack/Stdafx.h =================================================================== --- trunk/OpenMPT/mptrack/Stdafx.h 2009-01-10 11:10:49 UTC (rev 244) +++ trunk/OpenMPT/mptrack/Stdafx.h 2009-01-12 20:03:26 UTC (rev 245) @@ -72,6 +72,13 @@ #define WAVE_FORMAT_EXTENSIBLE 0xFFFE #endif // !defined(WAVE_FORMAT_EXTENSIBLE) +// Define to build without ASIO support; makes build possible without ASIO SDK. +//#define NO_ASIO + +// (HACK) Define to build without VST support; makes build possible without VST SDK. +//#define NO_VST + + void Log(LPCSTR format,...); #include "typedefs.h" Modified: trunk/OpenMPT/mptrack/VSTEditor.cpp =================================================================== --- trunk/OpenMPT/mptrack/VSTEditor.cpp 2009-01-10 11:10:49 UTC (rev 244) +++ trunk/OpenMPT/mptrack/VSTEditor.cpp 2009-01-12 20:03:26 UTC (rev 245) @@ -8,6 +8,7 @@ // +#ifndef NO_VST COwnerVstEditor::COwnerVstEditor(CVstPlugin *pPlugin) : CAbstractVstEditor(pPlugin) //----------------------------------------- @@ -129,3 +130,5 @@ m_pVstPlugin->Dispatch(effEditClose, 0, 0, NULL, 0); } } +#endif // NO_VST + Modified: trunk/OpenMPT/mptrack/VSTEditor.h =================================================================== --- trunk/OpenMPT/mptrack/VSTEditor.h 2009-01-10 11:10:49 UTC (rev 244) +++ trunk/OpenMPT/mptrack/VSTEditor.h 2009-01-12 20:03:26 UTC (rev 245) @@ -4,6 +4,8 @@ #include "VstPlug.h" #include "AbstractVstEditor.h" +#ifndef NO_VST + //============================== class COwnerVstEditor: public CAbstractVstEditor //============================== @@ -28,4 +30,7 @@ afx_msg void OnClose(); BOOL OpenEditor(CWnd *parent); VOID DoClose(); -}; \ No newline at end of file +}; + +#endif // NO_VST + Modified: trunk/OpenMPT/mptrack/View_gen.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_gen.cpp 2009-01-10 11:10:49 UTC (rev 244) +++ trunk/OpenMPT/mptrack/View_gen.cpp 2009-01-12 20:03:26 UTC (rev 245) @@ -914,6 +914,7 @@ void CViewGlobals::OnSelectPlugin() //--------------------------------- { +#ifndef NO_VST CModDoc *pModDoc = GetDocument(); if ((pModDoc) && (m_nCurrentPlugin < MAX_MIXPLUGINS)) @@ -934,6 +935,7 @@ //OnWetDryChanged(); // -! NEW_FEATURE#0014 } +#endif // NO_VST } Modified: trunk/OpenMPT/mptrack/Vstplug.cpp =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.cpp 2009-01-10 11:10:49 UTC (rev 244) +++ trunk/OpenMPT/mptrack/Vstplug.cpp 2009-01-12 20:03:26 UTC (rev 245) @@ -14,6 +14,7 @@ #include "defaultvsteditor.h" //rewbs.defaultPlugGUI #include "midi.h" +#ifndef NO_VST //#define VST_LOG //#define ENABLE_BUZZ @@ -4112,6 +4113,8 @@ else return 0; } +#endif // NO_VST + CString SNDMIXPLUGIN::GetParamName(const UINT index) const //-------------------------------------------------------- { Modified: trunk/OpenMPT/mptrack/Vstplug.h =================================================================== --- trunk/OpenMPT/mptrack/Vstplug.h 2009-01-10 11:10:49 UTC (rev 244) +++ trunk/OpenMPT/mptrack/Vstplug.h 2009-01-12 20:03:26 UTC (rev 245) @@ -1,7 +1,9 @@ #ifndef _VST_PLUGIN_MANAGER_H_ #define _VST_PLUGIN_MANAGER_H_ -#include <aeffectx.h> // VST +#ifndef NO_VST + #include <aeffectx.h> // VST +#endif #define kBuzzMagic 'Buzz' #define kDmoMagic 'DXMO' @@ -21,10 +23,11 @@ }; +#ifndef NO_VST + typedef AEffect * (VSTCALLBACK * PVSTPLUGENTRY)(audioMasterCallback); +#endif -typedef AEffect * (VSTCALLBACK * PVSTPLUGENTRY)(audioMasterCallback); - typedef struct _VSTPLUGINLIB { struct _VSTPLUGINLIB *pPrev, *pNext; @@ -53,7 +56,7 @@ friend class CAbstractVstEditor; //rewbs.defaultPlugGUI friend class COwnerVstEditor; //rewbs.defaultPlugGUI friend class CVstPluginManager; - +#ifndef NO_VST protected: enum {VSTEVENT_QUEUE_LEN=256}; @@ -191,6 +194,29 @@ private: short getMIDI14bitValueFromShort(short value); void MidiPitchBend(UINT nMidiCh, short pitchBendPos); +#else // case: NO_VST +public: + long GetNumParameters() {return 0;} + VOID GetParamName(UINT, LPSTR, UINT) {} + void ToggleEditor() {} + BOOL HasEditor() {return FALSE;} + UINT GetNumCommands() {return 0;} + VOID GetPluginType(LPSTR) {} + long GetNumPrograms() {return 0;} + long GetProgramNameIndexed(long, long, char*) {return 0;} + VOID SetParameter(UINT, FLOAT) {} + VOID GetParamLabel(UINT, LPSTR) {} + VOID GetParamDisplay(UINT, LPSTR) {} + FLOAT GetParameter(UINT) {return 0;} + bool LoadProgram(CString) {return false;} + bool SaveProgram(CString) {return false;} + VOID SetCurrentProgram(UINT) {} + BOOL ExecuteCommand(UINT) {return FALSE;} + void SetSlot(UINT) {} + void UpdateMixStructPtr(void*) {} + bool Bypass() {return false;} + +#endif // NO_VST }; @@ -198,6 +224,7 @@ class CVstPluginManager //===================== { +#ifndef NO_VST protected: PVSTPLUGINLIB m_pVstHead; @@ -222,6 +249,12 @@ static long VSTCALLBACK MasterCallBack(AEffect *effect, long opcode, long index, long value, void *ptr, float opt); static BOOL __cdecl CreateMixPluginProc(PSNDMIXPLUGIN, CSoundFile*); VstTimeInfo timeInfo; //rewbs.VSTcompliance +#else // NO_VST +public: + PVSTPLUGINLIB AddPlugin(LPCSTR, BOOL =TRUE, const bool = false, CString* const = 0) {return 0;} + PVSTPLUGINLIB GetFirstPlugin() const { return 0; } + VOID OnIdle() {} +#endif // NO_VST }; Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-01-10 11:10:49 UTC (rev 244) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-01-12 20:03:26 UTC (rev 245) @@ -13,7 +13,6 @@ #include "../mptrack/moddoc.h" #include "../mptrack/version.h" #include "sndfile.h" -#include "aeffectx.h" #include "wavConverter.h" #include "tuningcollection.h" #include <vector> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2009-01-17 22:48:58
|
Revision: 246 http://modplug.svn.sourceforge.net/modplug/?rev=246&view=rev Author: relabsoluness Date: 2009-01-17 21:37:21 +0000 (Sat, 17 Jan 2009) Log Message: ----------- (Patches from Jojo, merged somewhat modified) + Pattern tab: Ability to start playback with incoming MIDI note (see setup->MIDI) + Pattern tab: Duplicate channel (see channel header context menu). / General tab: VST volume slider is now disabled for S3M. / General tab: Initial channel volume controls are now enabled only for IT and MPTM. / Sample tab: Notes from MIDI should now be played like notes from keyboard. / Setup->MIDI: Minor text format changes. Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_gen.cpp trunk/OpenMPT/mptrack/Mainfrm.h trunk/OpenMPT/mptrack/Mpdlgs.cpp trunk/OpenMPT/mptrack/View_gen.cpp trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/mptrack/View_pat.h trunk/OpenMPT/mptrack/View_smp.cpp trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/soundlib/Sndfile.cpp Modified: trunk/OpenMPT/mptrack/Ctrl_gen.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_gen.cpp 2009-01-12 20:03:26 UTC (rev 245) +++ trunk/OpenMPT/mptrack/Ctrl_gen.cpp 2009-01-17 21:37:21 UTC (rev 246) @@ -203,20 +203,21 @@ m_SpinTempo.SetRange(specs.tempoMin, specs.tempoMax); m_SliderTempo.SetRange(0, specs.tempoMax - specs.tempoMin); - BOOL b = TRUE; - if (m_pSndFile->m_nType == MOD_TYPE_MOD) b = FALSE; - m_EditTempo.EnableWindow(b); - m_SpinTempo.EnableWindow(b); - m_EditSpeed.EnableWindow(b); - m_SpinSpeed.EnableWindow(b); - m_EditGlobalVol.EnableWindow(b); - m_SpinGlobalVol.EnableWindow(b); - m_EditVSTiVol.EnableWindow(b); - m_SpinVSTiVol.EnableWindow(b); - m_EditSamplePA.EnableWindow(b); - m_SpinSamplePA.EnableWindow(b); - m_SliderSamplePreAmp.EnableWindow(b); - m_SliderVSTiVol.EnableWindow(b); + const BOOL bIsNotMOD = (m_pSndFile->GetType() != MOD_TYPE_MOD); + const BOOL bIsNotMOD_S3M = ((bIsNotMOD) && (m_pSndFile->GetType() != MOD_TYPE_S3M)); + m_EditTempo.EnableWindow(bIsNotMOD); + m_SpinTempo.EnableWindow(bIsNotMOD); + m_EditSpeed.EnableWindow(bIsNotMOD); + m_SpinSpeed.EnableWindow(bIsNotMOD); + m_EditGlobalVol.EnableWindow(bIsNotMOD); + m_SpinGlobalVol.EnableWindow(bIsNotMOD); + m_EditSamplePA.EnableWindow(bIsNotMOD); + m_SpinSamplePA.EnableWindow(bIsNotMOD); + m_SliderSamplePreAmp.EnableWindow(bIsNotMOD); + m_SliderVSTiVol.EnableWindow(bIsNotMOD_S3M); + m_EditVSTiVol.EnableWindow(bIsNotMOD_S3M); + m_SpinVSTiVol.EnableWindow(bIsNotMOD_S3M); + //Note: Global volume slider is not disabled for MOD //on purpose(can be used to control play volume) Modified: trunk/OpenMPT/mptrack/Mainfrm.h =================================================================== --- trunk/OpenMPT/mptrack/Mainfrm.h 2009-01-12 20:03:26 UTC (rev 245) +++ trunk/OpenMPT/mptrack/Mainfrm.h 2009-01-17 21:37:21 UTC (rev 246) @@ -229,6 +229,7 @@ #define MIDISETUP_RESPONDTOPLAYCONTROLMSGS 0x20 #define MIDISETUP_AMPLIFYVELOCITY 0x40 #define MIDISETUP_MIDIMACROCONTROL 0x80 +#define MIDISETUP_PLAYPATTERNONMIDIIN 0x100 Modified: trunk/OpenMPT/mptrack/Mpdlgs.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mpdlgs.cpp 2009-01-12 20:03:26 UTC (rev 245) +++ trunk/OpenMPT/mptrack/Mpdlgs.cpp 2009-01-17 21:37:21 UTC (rev 246) @@ -1093,6 +1093,7 @@ ON_COMMAND(IDC_MIDI_MACRO_CONTROL, OnSettingsChanged) ON_COMMAND(IDC_MIDIVOL_TO_NOTEVOL, OnSettingsChanged) ON_COMMAND(IDC_MIDIPLAYCONTROL, OnSettingsChanged) + ON_COMMAND(IDC_MIDIPLAYPATTERNONMIDIIN, OnSettingsChanged) END_MESSAGE_MAP() @@ -1123,6 +1124,7 @@ if (m_dwMidiSetup & MIDISETUP_MIDIMACROCONTROL) CheckDlgButton(IDC_MIDI_MACRO_CONTROL, MF_CHECKED); if (m_dwMidiSetup & MIDISETUP_MIDIVOL_TO_NOTEVOL) CheckDlgButton(IDC_MIDIVOL_TO_NOTEVOL, MF_CHECKED); if (m_dwMidiSetup & MIDISETUP_RESPONDTOPLAYCONTROLMSGS) CheckDlgButton(IDC_MIDIPLAYCONTROL, MF_CHECKED); + if (m_dwMidiSetup & MIDISETUP_PLAYPATTERNONMIDIIN) CheckDlgButton(IDC_MIDIPLAYPATTERNONMIDIIN, MF_CHECKED); // Midi In Device if ((combo = (CComboBox *)GetDlgItem(IDC_COMBO1)) != NULL) { @@ -1159,6 +1161,7 @@ if (IsDlgButtonChecked(IDC_MIDI_MACRO_CONTROL)) m_dwMidiSetup |= MIDISETUP_MIDIMACROCONTROL; if (IsDlgButtonChecked(IDC_MIDIVOL_TO_NOTEVOL)) m_dwMidiSetup |= MIDISETUP_MIDIVOL_TO_NOTEVOL; if (IsDlgButtonChecked(IDC_MIDIPLAYCONTROL)) m_dwMidiSetup |= MIDISETUP_RESPONDTOPLAYCONTROLMSGS; + if (IsDlgButtonChecked(IDC_MIDIPLAYPATTERNONMIDIIN)) m_dwMidiSetup |= MIDISETUP_PLAYPATTERNONMIDIIN; if ((combo = (CComboBox *)GetDlgItem(IDC_COMBO1)) != NULL) { Modified: trunk/OpenMPT/mptrack/View_gen.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_gen.cpp 2009-01-12 20:03:26 UTC (rev 245) +++ trunk/OpenMPT/mptrack/View_gen.cpp 2009-01-17 21:37:21 UTC (rev 246) @@ -393,11 +393,13 @@ BOOL bIT = ((bEnable) && (pSndFile->m_nType & (MOD_TYPE_IT|MOD_TYPE_MPT))); ::EnableWindow(::GetDlgItem(m_hWnd, IDC_CHECK1+ichn*2), bEnable); ::EnableWindow(::GetDlgItem(m_hWnd, IDC_CHECK2+ichn*2), bIT); - ::EnableWindow(m_sbVolume[ichn].m_hWnd, bEnable); + + ::EnableWindow(m_sbVolume[ichn].m_hWnd, bIT); + ::EnableWindow(m_spinVolume[ichn], bIT); + ::EnableWindow(m_sbPan[ichn].m_hWnd, bEnable && !(pSndFile->GetType() & (MOD_TYPE_XM|MOD_TYPE_MOD))); - ::EnableWindow(m_spinVolume[ichn], bEnable); ::EnableWindow(m_spinPan[ichn], bEnable && !(pSndFile->GetType() & (MOD_TYPE_XM|MOD_TYPE_MOD))); - ::EnableWindow(::GetDlgItem(m_hWnd, IDC_EDIT1+ichn*2), bEnable); + ::EnableWindow(::GetDlgItem(m_hWnd, IDC_EDIT1+ichn*2), bIT); ::EnableWindow(::GetDlgItem(m_hWnd, IDC_EDIT2+ichn*2), bEnable && !(pSndFile->GetType() & (MOD_TYPE_XM|MOD_TYPE_MOD))); ::EnableWindow(::GetDlgItem(m_hWnd, IDC_EDIT9+ichn), ((bEnable) && (pSndFile->m_nType & (MOD_TYPE_XM|MOD_TYPE_IT|MOD_TYPE_MPT)))); m_CbnEffects[ichn].EnableWindow(bEnable); Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2009-01-12 20:03:26 UTC (rev 245) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-01-17 21:37:21 UTC (rev 246) @@ -99,6 +99,7 @@ ON_COMMAND(ID_PATTERN_SETINSTRUMENT, OnSetSelInstrument) ON_COMMAND(ID_PATTERN_ADDCHANNEL_FRONT, OnAddChannelFront) ON_COMMAND(ID_PATTERN_ADDCHANNEL_AFTER, OnAddChannelAfter) + ON_COMMAND(ID_PATTERN_DUPLICATECHANNEL, OnDuplicateChannel) ON_COMMAND(ID_PATTERN_REMOVECHANNEL, OnRemoveChannel) ON_COMMAND(ID_PATTERN_REMOVECHANNELDIALOG, OnRemoveChannelDialog) ON_COMMAND(ID_CURSORCOPY, OnCursorCopy) @@ -2505,6 +2506,46 @@ EndWaitCursor(); } +void CViewPattern::OnDuplicateChannel() +//------------------------------------ +{ + CModDoc *pModDoc = GetDocument(); + CSoundFile* pSndFile; + if (pModDoc == 0 || (pSndFile = pModDoc->GetSoundFile()) == 0) + return; + + if(AfxMessageBox(GetStrI18N(_TEXT("This affects all patterns, proceed?")), MB_YESNO) != IDYES) + return; + + const CHANNELINDEX nDupChn = GetChanFromCursor(m_nMenuParam); + if(nDupChn >= pSndFile->GetNumChannels()) + return; + + CHANNELINDEX nNumChnNew = pSndFile->GetNumChannels()+1; + // Create vector {0, 1,..., n-1, n, n, n+1, n+2, ..., nNumChnNew-2), where n = nDupChn. + vector<CHANNELINDEX> vecChns(nNumChnNew); + CHANNELINDEX i = 0; + for(i = 0; i<nDupChn+1; i++) + vecChns[i] = i; + vecChns[i] = nDupChn; + i++; + for(; i<nNumChnNew; i++) + vecChns[i] = i-1; + + nNumChnNew = pSndFile->ReArrangeChannels(vecChns); + + // Check that duplication happened and in that case update. + if(nNumChnNew == vecChns.size()) + { + pModDoc->SetModified(); + pModDoc->ClearUndo(); + pModDoc->UpdateAllViews(NULL, HINT_MODCHANNELS); + pModDoc->UpdateAllViews(NULL, HINT_MODTYPE); + SetCurrentPattern(m_nPattern); + } + +} + void CViewPattern::OnRunScript() //-------------------------------- { @@ -2945,6 +2986,11 @@ if(nVol < 0) nVol = -1; else nVol = (nVol + 3) / 4; //Value from [0,256] to [0,64] TempEnterNote(nNote, true, nVol); + + // continue playing as soon as MIDI notes are being received (request 2813) + if(pSndFile->IsPaused() && CMainFrame::m_dwMidiSetup & MIDISETUP_PLAYPATTERNONMIDIIN) + pModDoc->OnPatternPlayNoLoop(); + break; case 0xB: //Controller change @@ -4659,11 +4705,14 @@ //Not doing the menuentries if opted to use old style menu style. AppendMenu(hMenu, MF_SEPARATOR, 0, ""); + + AppendMenu(hMenu, MF_STRING, ID_PATTERN_DUPLICATECHANNEL, "Duplicate this channel"); + HMENU addChannelMenu = ::CreatePopupMenu(); AppendMenu(hMenu, MF_POPUP, (UINT)addChannelMenu, "Add channel\t"); AppendMenu(addChannelMenu, MF_STRING, ID_PATTERN_ADDCHANNEL_FRONT, "Before this channel"); AppendMenu(addChannelMenu, MF_STRING, ID_PATTERN_ADDCHANNEL_AFTER, "After this channel"); - + HMENU removeChannelMenu = ::CreatePopupMenu(); AppendMenu(hMenu, MF_POPUP, (UINT)removeChannelMenu, "Remove channel\t"); AppendMenu(removeChannelMenu, MF_STRING, ID_PATTERN_REMOVECHANNEL, "Remove this channel\t"); Modified: trunk/OpenMPT/mptrack/View_pat.h =================================================================== --- trunk/OpenMPT/mptrack/View_pat.h 2009-01-12 20:03:26 UTC (rev 245) +++ trunk/OpenMPT/mptrack/View_pat.h 2009-01-17 21:37:21 UTC (rev 246) @@ -268,6 +268,7 @@ afx_msg void OnSetSelInstrument(); afx_msg void OnAddChannelFront(); afx_msg void OnAddChannelAfter(); + afx_msg void OnDuplicateChannel(); afx_msg void OnRemoveChannel(); afx_msg void OnRemoveChannelDialog(); afx_msg void OnPatternProperties(); Modified: trunk/OpenMPT/mptrack/View_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_smp.cpp 2009-01-12 20:03:26 UTC (rev 245) +++ trunk/OpenMPT/mptrack/View_smp.cpp 2009-01-17 21:37:21 UTC (rev 246) @@ -2307,7 +2307,8 @@ if (midibyte2 & 0x7F) { nVol = ApplyVolumeRelatedMidiSettings(dwMidiData, midivolume); - pModDoc->PlayNote(nNote, 0, m_nSample, FALSE, nVol); + //pModDoc->PlayNote(nNote, 0, m_nSample, FALSE, nVol); + PlayNote(nNote); } break; Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2009-01-12 20:03:26 UTC (rev 245) +++ trunk/OpenMPT/mptrack/mptrack.rc 2009-01-17 21:37:21 UTC (rev 246) @@ -462,49 +462,52 @@ IDD_MIDISETUP DIALOGEX 0, 0, 272, 281 STYLE DS_SETFONT | DS_3DLOOK | WS_CHILD | WS_DISABLED | WS_CAPTION -CAPTION "Midi" +CAPTION "MIDI" FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN - GROUPBOX "Midi Recording",IDC_STATIC,5,5,260,185 - LTEXT "Midi Input Device:",IDC_STATIC,15,20,67,8 + GROUPBOX "MIDI Recording",IDC_STATIC,5,5,260,200 + LTEXT "MIDI Input Device:",IDC_STATIC,15,20,67,8 COMBOBOX IDC_COMBO1,15,30,120,74,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Midi Output Device:",IDC_STATIC,140,20,65,8,NOT + LTEXT "MIDI Output Device:",IDC_STATIC,140,20,65,8,NOT WS_VISIBLE COMBOBOX IDC_COMBO2,140,30,120,73,CBS_DROPDOWNLIST | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP CONTROL "Apply Octave Transpose on external midi keyboard", IDC_CHECK4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,55, 185,9 - CONTROL "Amplify Midi Velocity",IDC_CHECK3,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,15,90,113,9 + CONTROL "Amplify MIDI velocity",IDC_CHECK3,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,15,90,100,9 CONTROL "Record note velocity",IDC_CHECK1,"Button", - BS_AUTOCHECKBOX | BS_TOP | WS_TABSTOP,15,75,132,9 + BS_AUTOCHECKBOX | BS_TOP | WS_TABSTOP,15,75,100,9 CONTROL "Record Note Off (Instruments Only)",IDC_CHECK2,"Button", BS_AUTOCHECKBOX | WS_TABSTOP,15,120,130,9 - GROUPBOX "Midi file import",IDC_STATIC,5,200,260,45 - LTEXT "Speed:",IDC_STATIC,15,220,24,8 - EDITTEXT IDC_EDIT1,45,220,39,12,ES_AUTOHSCROLL | ES_NUMBER + GROUPBOX "MIDI file import",IDC_STATIC,5,210,260,45 + LTEXT "Speed:",IDC_STATIC,15,230,24,8 + EDITTEXT IDC_EDIT1,45,230,39,12,ES_AUTOHSCROLL | ES_NUMBER CONTROL "Spin1",IDC_SPIN1,"msctls_updown32",UDS_SETBUDDYINT | - UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,79,225, + UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,79,235, 11,14 - LTEXT "Pattern size:",IDC_STATIC,115,220,40,8 - EDITTEXT IDC_EDIT2,165,220,39,12,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "Pattern size:",IDC_STATIC,115,230,40,8 + EDITTEXT IDC_EDIT2,165,230,39,12,ES_AUTOHSCROLL | ES_NUMBER CONTROL "Spin1",IDC_SPIN2,"msctls_updown32",UDS_SETBUDDYINT | - UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,196,222, + UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_NOTHOUSANDS,196,232, 11,14 CONTROL "Pass MIDI to active instrument plugin (experimental)", IDC_MIDI_TO_PLUGIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 15,155,222,9 - CONTROL "Combine midi volume to note velocity", + 15,155,180,9 + CONTROL "Combine MIDI volume to note velocity", IDC_MIDIVOL_TO_NOTEVOL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,105,139,9 CONTROL "Respond to play/continue/stop song messages (untested)", IDC_MIDIPLAYCONTROL,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,15,170,202,9 + WS_TABSTOP,15,170,200,9 CONTROL "Record MIDI controller changes as MIDI macro changes (in pattern)", IDC_MIDI_MACRO_CONTROL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,140,226,9 + CONTROL "Continue song as soon as MIDI notes are being received", + IDC_MIDIPLAYPATTERNONMIDIIN,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,15,185,195,10 END IDD_LOADRAWSAMPLE DIALOG 0, 0, 168, 84 Modified: trunk/OpenMPT/mptrack/resource.h =================================================================== --- trunk/OpenMPT/mptrack/resource.h 2009-01-12 20:03:26 UTC (rev 245) +++ trunk/OpenMPT/mptrack/resource.h 2009-01-17 21:37:21 UTC (rev 246) @@ -824,6 +824,7 @@ #define IDC_TEXT_STRETCHPARAMS 2337 #define IDC_EDIT_STRETCHPARAMS 2338 #define IDC_MIDI_MACRO_CONTROL 2339 +#define IDC_MIDIPLAYPATTERNONMIDIIN 2340 #define ID_FILE_NEWMOD 32771 #define ID_FILE_NEWXM 32772 #define ID_FILE_NEWS3M 32773 @@ -1048,6 +1049,7 @@ #define ID_VIEW_MIDIMAPPING 59211 #define ID_NETLINK_OPENMPTWIKI_GERMAN 59213 #define ID_NETLINK_MODARCHIVE 59214 +#define ID_PATTERN_DUPLICATECHANNEL 59216 // Next default values for new objects // @@ -1055,8 +1057,8 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 516 -#define _APS_NEXT_COMMAND_VALUE 59215 -#define _APS_NEXT_CONTROL_VALUE 2340 +#define _APS_NEXT_COMMAND_VALUE 59217 +#define _APS_NEXT_CONTROL_VALUE 2341 #define _APS_NEXT_SYMED_VALUE 901 #endif #endif Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-01-12 20:03:26 UTC (rev 245) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-01-17 21:37:21 UTC (rev 246) @@ -1453,7 +1453,8 @@ if(nRemainingChannels > GetModSpecifications().channelsMax || nRemainingChannels < GetModSpecifications().channelsMin) { - CString str = "Error: Bad newOrder vector in CSoundFile::ReArrangeChannels(...)"; + CString str; + str.Format(GetStrI18N(_TEXT("Can't apply change: Number of channels should be within [%u,%u]")), GetModSpecifications().channelsMin, GetModSpecifications().channelsMax); CMainFrame::GetMainFrame()->MessageBox(str , "ReArrangeChannels", MB_OK | MB_ICONINFORMATION); return 0; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2009-01-23 18:49:57
|
Revision: 247 http://modplug.svn.sourceforge.net/modplug/?rev=247&view=rev Author: relabsoluness Date: 2009-01-23 18:49:52 +0000 (Fri, 23 Jan 2009) Log Message: ----------- ? Minor internal tweaks. Modified Paths: -------------- trunk/OpenMPT/mptrack/misc_util.h trunk/OpenMPT/mptrack/serialization_utils.h trunk/OpenMPT/mptrack/test/test.cpp trunk/OpenMPT/mptrack/typedefs.h trunk/OpenMPT/soundlib/tuningCollection.cpp trunk/OpenMPT/soundlib/tuningcollection.h Modified: trunk/OpenMPT/mptrack/misc_util.h =================================================================== --- trunk/OpenMPT/mptrack/misc_util.h 2009-01-17 21:37:21 UTC (rev 246) +++ trunk/OpenMPT/mptrack/misc_util.h 2009-01-23 18:49:52 UTC (rev 247) @@ -7,9 +7,7 @@ #define ARRAYELEMCOUNT(x) (sizeof(x)/sizeof(x[0])) //Compile time assert. -#define STATIC_ASSERT(expr) typedef char ___staticAssertTypedef[(expr)]; -STATIC_ASSERT(true); //STATIC_ASSERT(false) doesn't necessarily cause error on some compilers - //if used alone. Using STATIC_ASSERT(true) first should make sure it does. +#define STATIC_ASSERT(expr) C_ASSERT(expr) //Convert object(typically number) to string template<class T> Modified: trunk/OpenMPT/mptrack/serialization_utils.h =================================================================== --- trunk/OpenMPT/mptrack/serialization_utils.h 2009-01-17 21:37:21 UTC (rev 246) +++ trunk/OpenMPT/mptrack/serialization_utils.h 2009-01-23 18:49:52 UTC (rev 247) @@ -10,6 +10,7 @@ #include <algorithm> #include "misc_util.h" #include "typedefs.h" +#include <limits> using std::numeric_limits; using std::ostringstream; Modified: trunk/OpenMPT/mptrack/test/test.cpp =================================================================== --- trunk/OpenMPT/mptrack/test/test.cpp 2009-01-17 21:37:21 UTC (rev 246) +++ trunk/OpenMPT/mptrack/test/test.cpp 2009-01-23 18:49:52 UTC (rev 247) @@ -7,6 +7,7 @@ #include "test.h" #include "../version.h" #include "../misc_util.h" +#include <limits> #ifdef ENABLE_TESTS @@ -41,6 +42,7 @@ void TestVersion(); +void TestTypes(); @@ -49,6 +51,7 @@ //------------ { DO_TEST(TestVersion); + DO_TEST(TestTypes); MessageBox(0, "Tests were run", "Testing", MB_ICONINFORMATION); } @@ -112,6 +115,30 @@ } } + +void TestTypes() +//-------------- +{ + VERIFY_EQUAL(int8_min, (std::numeric_limits<int8>::min)()); + VERIFY_EQUAL(int8_max, (std::numeric_limits<int8>::max)()); + VERIFY_EQUAL(uint8_max, (std::numeric_limits<uint8>::max)()); + + VERIFY_EQUAL(int16_min, (std::numeric_limits<int16>::min)()); + VERIFY_EQUAL(int16_max, (std::numeric_limits<int16>::max)()); + VERIFY_EQUAL(uint16_max, (std::numeric_limits<uint16>::max)()); + + VERIFY_EQUAL(int32_min, (std::numeric_limits<int32>::min)()); + VERIFY_EQUAL(int32_max, (std::numeric_limits<int32>::max)()); + VERIFY_EQUAL(uint32_max, (std::numeric_limits<uint32>::max)()); + + VERIFY_EQUAL(int64_min, (std::numeric_limits<int64>::min)()); + VERIFY_EQUAL(int64_max, (std::numeric_limits<int64>::max)()); + VERIFY_EQUAL(uint64_max, (std::numeric_limits<uint64>::max)()); + + VERIFY_EQUAL(ROWINDEX_MAX, (std::numeric_limits<ROWINDEX>::max)()); + VERIFY_EQUAL(ORDERINDEX_MAX, (std::numeric_limits<ORDERINDEX>::max)()); +} + }; //Namespace MptTest #else //Case: ENABLE_TESTS is not defined. Modified: trunk/OpenMPT/mptrack/typedefs.h =================================================================== --- trunk/OpenMPT/mptrack/typedefs.h 2009-01-17 21:37:21 UTC (rev 246) +++ trunk/OpenMPT/mptrack/typedefs.h 2009-01-23 18:49:52 UTC (rev 247) @@ -1,8 +1,6 @@ #ifndef TYPEDEFS_H #define TYPEDEFS_H -#include <limits> - typedef __int8 int8; typedef __int16 int16; typedef __int32 int32; @@ -13,27 +11,29 @@ typedef unsigned __int32 uint32; typedef unsigned __int64 uint64; -const int8 int8_min = (std::numeric_limits<int8>::min)(); -const int16 int16_min = (std::numeric_limits<int16>::min)(); -const int32 int32_min = (std::numeric_limits<int32>::min)(); -const int64 int64_min = (std::numeric_limits<int64>::min)(); +const int8 int8_min = -127-1; +const int16 int16_min = -32767-1; +const int32 int32_min = -2147483647-1; +const int64 int64_min = -9223372036854775807-1; -const int8 int8_max = (std::numeric_limits<int8>::max)(); -const int16 int16_max = (std::numeric_limits<int16>::max)(); -const int32 int32_max = (std::numeric_limits<int32>::max)(); -const int64 int64_max = (std::numeric_limits<int64>::max)(); +const int8 int8_max = 127; +const int16 int16_max = 32767; +const int32 int32_max = 2147483647; +const int64 int64_max = 9223372036854775807; -const uint8 uint8_max = (std::numeric_limits<uint8>::max)(); -const uint16 uint16_max = (std::numeric_limits<uint16>::max)(); -const uint32 uint32_max = (std::numeric_limits<uint32>::max)(); -const uint64 uint64_max = (std::numeric_limits<uint64>::max)(); +const uint8 uint8_max = 255; +const uint16 uint16_max = 65535; +const uint32 uint32_max = 4294967295; +const uint64 uint64_max = 18446744073709551615; typedef float float32; typedef uint32 ROWINDEX; + const ROWINDEX ROWINDEX_MAX = uint32_max; typedef uint16 CHANNELINDEX; typedef uint16 ORDERINDEX; + const ORDERINDEX ORDERINDEX_MAX = uint16_max; typedef uint16 PATTERNINDEX; typedef uint8 PLUGINDEX; typedef uint16 TEMPO; @@ -41,8 +41,5 @@ typedef uint16 INSTRUMENTINDEX; typedef uint32 MODTYPE; -const ORDERINDEX ORDERINDEX_MAX = (std::numeric_limits<ORDERINDEX>::max)(); -const ROWINDEX ROWINDEX_MAX = (std::numeric_limits<ROWINDEX>::max)(); - #endif Modified: trunk/OpenMPT/soundlib/tuningCollection.cpp =================================================================== --- trunk/OpenMPT/soundlib/tuningCollection.cpp 2009-01-17 21:37:21 UTC (rev 246) +++ trunk/OpenMPT/soundlib/tuningCollection.cpp 2009-01-23 18:49:52 UTC (rev 247) @@ -4,7 +4,7 @@ #include <bitset> //Serializations statics: -const CTuningCollection::SERIALIZATION_VERSION CTuningCollection::s_SerializationVersion = 3; +//const CTuningCollection::SERIALIZATION_VERSION CTuningCollection::s_SerializationVersion = 3; /* Version history: @@ -15,18 +15,8 @@ using namespace std; - -const CTuningCollection::SERIALIZATION_RETURN_TYPE CTuningCollection::SERIALIZATION_SUCCESS = false; -const CTuningCollection::SERIALIZATION_RETURN_TYPE CTuningCollection::SERIALIZATION_FAILURE = true; - const string CTuningCollection::s_FileExtension = ".tc"; -//BUG(?): These might not be called before constructor for certain -//CTuningCollection objects - not good. -const CTuningCollection::EDITMASK CTuningCollection::EM_ADD = 1; //0..01 -const CTuningCollection::EDITMASK CTuningCollection::EM_REMOVE = 2; //0..010 -const CTuningCollection::EDITMASK CTuningCollection::EM_ALLOWALL = 0xFFFF; -const CTuningCollection::EDITMASK CTuningCollection::EM_CONST = 0; /* TODOS: @@ -35,7 +25,7 @@ -CTuningCollection::CTuningCollection(const string& name) : m_Name(name), m_EditMask(0xFFFF) +CTuningCollection::CTuningCollection(const string& name) : m_Name(name), m_EditMask(EM_ALLOWALL) //------------------------------------ { if(m_Name.size() > GetNameLengthMax()) m_Name.resize(GetNameLengthMax()); Modified: trunk/OpenMPT/soundlib/tuningcollection.h =================================================================== --- trunk/OpenMPT/soundlib/tuningcollection.h 2009-01-17 21:37:21 UTC (rev 246) +++ trunk/OpenMPT/soundlib/tuningcollection.h 2009-01-23 18:49:52 UTC (rev 247) @@ -31,15 +31,18 @@ //BEGIN PUBLIC STATIC CONSTS public: - static const EDITMASK EM_ADD; //true <~> allowed - static const EDITMASK EM_REMOVE; - static const EDITMASK EM_ALLOWALL; - static const EDITMASK EM_CONST; + enum + { + EM_ADD = 1, //true <~> allowed + EM_REMOVE = 2, + EM_ALLOWALL = 0xffff, + EM_CONST = 0, - static const SERIALIZATION_VERSION s_SerializationVersion; + s_SerializationVersion = 3, - static const SERIALIZATION_RETURN_TYPE SERIALIZATION_SUCCESS; - static const SERIALIZATION_RETURN_TYPE SERIALIZATION_FAILURE; + SERIALIZATION_SUCCESS = false, + SERIALIZATION_FAILURE = true + }; static const string s_FileExtension; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2009-01-29 20:46:57
|
Revision: 248 http://modplug.svn.sourceforge.net/modplug/?rev=248&view=rev Author: relabsoluness Date: 2009-01-29 20:46:51 +0000 (Thu, 29 Jan 2009) Log Message: ----------- (Patches from Jojo, merged somewhat modified) + General: With additional DLL(not included), can now import MO3 files. + Pattern: Descriptions to tremor and retrigger note command parameters in note properties dialog. / Pattern: When applying "change instrument", won't add instrument number to note off/cut if the note doesn't have instrument already. / Menu: Goto dialog can now be opened from Edit-menu. . Song Cleanup: Sample cleanup should no longer remove data after sustain loop end point. . GUI: Minor tweaks (changes to MIDI mapping dialog, Channelmanager window should no longer be visible in taskbar, text format changes). Modified Paths: -------------- trunk/OpenMPT/mptrack/ChannelManagerDlg.cpp trunk/OpenMPT/mptrack/InputHandler.cpp trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/mptrack/Stdafx.h trunk/OpenMPT/mptrack/View_pat.cpp trunk/OpenMPT/mptrack/View_tre.cpp trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/mptrack/mptrack.vcproj trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h Added Paths: ----------- trunk/OpenMPT/soundlib/Load_mo3.cpp Modified: trunk/OpenMPT/mptrack/ChannelManagerDlg.cpp =================================================================== --- trunk/OpenMPT/mptrack/ChannelManagerDlg.cpp 2009-01-23 18:49:52 UTC (rev 247) +++ trunk/OpenMPT/mptrack/ChannelManagerDlg.cpp 2009-01-29 20:46:51 UTC (rev 248) @@ -612,27 +612,27 @@ if((button = GetDlgItem(IDC_BUTTON1)) != 0){ button->GetWindowRect(&btn); - button->SetWindowPos(NULL,btn.left-wnd.left-3,wnd.Height()-btn.Height()*2-6,0,0,SWP_NOSIZE | SWP_NOZORDER); + button->SetWindowPos(NULL,btn.left-wnd.left-3,wnd.Height()-btn.Height()*2-4,0,0,SWP_NOSIZE | SWP_NOZORDER); } if((button = GetDlgItem(IDC_BUTTON2)) != 0){ button->GetWindowRect(&btn); - button->SetWindowPos(NULL,btn.left-wnd.left-3,wnd.Height()-btn.Height()*2-6,0,0,SWP_NOSIZE | SWP_NOZORDER); + button->SetWindowPos(NULL,btn.left-wnd.left-3,wnd.Height()-btn.Height()*2-4,0,0,SWP_NOSIZE | SWP_NOZORDER); } if((button = GetDlgItem(IDC_BUTTON3)) != 0){ button->GetWindowRect(&btn); - button->SetWindowPos(NULL,btn.left-wnd.left-3,wnd.Height()-btn.Height()*2-6,0,0,SWP_NOSIZE | SWP_NOZORDER); + button->SetWindowPos(NULL,btn.left-wnd.left-3,wnd.Height()-btn.Height()*2-4,0,0,SWP_NOSIZE | SWP_NOZORDER); } if((button = GetDlgItem(IDC_BUTTON4)) != 0){ button->GetWindowRect(&btn); - button->SetWindowPos(NULL,btn.left-wnd.left-3,wnd.Height()-btn.Height()*2-6,0,0,SWP_NOSIZE | SWP_NOZORDER); + button->SetWindowPos(NULL,btn.left-wnd.left-3,wnd.Height()-btn.Height()*2-4,0,0,SWP_NOSIZE | SWP_NOZORDER); } if((button = GetDlgItem(IDC_BUTTON5)) != 0){ button->GetWindowRect(&btn); - button->SetWindowPos(NULL,btn.left-wnd.left-3,wnd.Height()-btn.Height()*2-6,0,0,SWP_NOSIZE | SWP_NOZORDER); + button->SetWindowPos(NULL,btn.left-wnd.left-3,wnd.Height()-btn.Height()*2-4,0,0,SWP_NOSIZE | SWP_NOZORDER); } if((button = GetDlgItem(IDC_BUTTON6)) != 0){ button->GetWindowRect(&btn); - button->SetWindowPos(NULL,btn.left-wnd.left-3,wnd.Height()-btn.Height()*2-6,0,0,SWP_NOSIZE | SWP_NOZORDER); + button->SetWindowPos(NULL,btn.left-wnd.left-3,wnd.Height()-btn.Height()*2-4,0,0,SWP_NOSIZE | SWP_NOZORDER); } GetClientRect(&wnd); Modified: trunk/OpenMPT/mptrack/InputHandler.cpp =================================================================== --- trunk/OpenMPT/mptrack/InputHandler.cpp 2009-01-23 18:49:52 UTC (rev 247) +++ trunk/OpenMPT/mptrack/InputHandler.cpp 2009-01-29 20:46:51 UTC (rev 248) @@ -396,7 +396,7 @@ case ID_FILE_SAVEASMP3: s="Save as MP3...\t"; c=kcFileSaveAsMP3; break; case ID_FILE_SAVEMIDI: s="Export as Midi...\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; + case ID_IMPORT_MIDILIB: s="Import MIDI Library...\t"; c=kcFileImportMidiLib; break; case ID_ADD_SOUNDBANK: s="Add Sound Bank...\t"; c=kcFileAddSoundBank; break; case ID_PLAYER_PLAY: s="Pause/Resume\t"; c= kcPlayPauseSong; break; Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-01-23 18:49:52 UTC (rev 247) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-01-29 20:46:51 UTC (rev 248) @@ -182,6 +182,7 @@ } f.Close(); } + EndWaitCursor(); if ((m_SndFile.m_nType == MOD_TYPE_NONE) || (!m_SndFile.m_nChannels)) return FALSE; // Midi Import @@ -2466,6 +2467,37 @@ wsprintf(s, "%dbpm", param); break; + case CMD_TREMOR: + if(param) + wsprintf(s, "ontime %d, offtime %d", param >> 4, param & 0x0F); + else + strcpy(s, "continue"); + break; + + case CMD_RETRIG: + switch(param >> 4) { + case 0: strcpy(s, "continue"); break; + case 1: strcpy(s, "vol -1"); break; + case 2: strcpy(s, "vol -2"); break; + case 3: strcpy(s, "vol -4"); break; + case 4: strcpy(s, "vol -8"); break; + case 5: strcpy(s, "vol -16"); break; + case 6: strcpy(s, "vol *0.66"); break; + case 7: strcpy(s, "vol *0.5"); break; + case 8: strcpy(s, "vol *1"); break; + case 9: strcpy(s, "vol +1"); break; + case 10: strcpy(s, "vol +2"); break; + case 11: strcpy(s, "vol +4"); break; + case 12: strcpy(s, "vol +8"); break; + case 13: strcpy(s, "vol +16"); break; + case 14: strcpy(s, "vol *1.5"); break; + case 15: strcpy(s, "vol *2"); break; + } + char spd[10]; + wsprintf(spd, " speed %d", param & 0x0F); + strcat(s, spd); + break; + case CMD_VOLUMESLIDE: case CMD_TONEPORTAVOL: case CMD_VIBRATOVOL: Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-01-23 18:49:52 UTC (rev 247) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-01-29 20:46:51 UTC (rev 248) @@ -770,9 +770,8 @@ } for (UINT ilo=1; ilo<=m_SndFile.m_nSamples; ilo++) if (m_SndFile.Ins[ilo].pSample) { - if ((m_SndFile.Ins[ilo].uFlags & (CHN_LOOP|CHN_SUSTAINLOOP)) - && (m_SndFile.Ins[ilo].nLength > m_SndFile.Ins[ilo].nLoopEnd + 2) - && (m_SndFile.Ins[ilo].nLength > m_SndFile.Ins[ilo].nSustainEnd + 2)) nLoopOpt++; + if ((m_SndFile.Ins[ilo].uFlags & CHN_LOOP) + && (m_SndFile.Ins[ilo].nLength > m_SndFile.Ins[ilo].nLoopEnd + 2)) nLoopOpt++; } if (nLoopOpt) { @@ -782,12 +781,10 @@ { for (UINT j=1; j<=m_SndFile.m_nSamples; j++) { - if ((m_SndFile.Ins[j].uFlags & (CHN_LOOP|CHN_SUSTAINLOOP)) - && (m_SndFile.Ins[j].nLength > m_SndFile.Ins[j].nLoopEnd + 2) - && (m_SndFile.Ins[j].nLength > m_SndFile.Ins[j].nSustainEnd + 2)) + if ((m_SndFile.Ins[j].uFlags & CHN_LOOP) + && (m_SndFile.Ins[j].nLength > m_SndFile.Ins[j].nLoopEnd + 2)) { UINT lmax = m_SndFile.Ins[j].nLoopEnd + 2; - if (m_SndFile.Ins[j].nSustainEnd + 2 > lmax) lmax = m_SndFile.Ins[j].nSustainEnd + 2; if ((lmax < m_SndFile.Ins[j].nLength) && (lmax >= 16)) m_SndFile.Ins[j].nLength = lmax; } } Modified: trunk/OpenMPT/mptrack/Mptrack.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.cpp 2009-01-23 18:49:52 UTC (rev 247) +++ trunk/OpenMPT/mptrack/Mptrack.cpp 2009-01-29 20:46:51 UTC (rev 248) @@ -302,7 +302,7 @@ UINT id = IDYES; if (!bNoWarn) { - id = CMainFrame::GetMainFrame()->MessageBox("You are about to replace the current midi library:\n" + id = CMainFrame::GetMainFrame()->MessageBox("You are about to replace the current MIDI library:\n" "Do you want to replace only the missing instruments? (recommended)", "Warning", MB_YESNOCANCEL|MB_ICONQUESTION ); } @@ -1248,9 +1248,14 @@ // -> CODE#0023 // -> DESC="IT project files (.itp)" // "All Modules|*.mod;*.nst;*.wow;*.s3m;*.stm;*.669;*.mtm;*.xm;*.it;*.ult;*.mdz;*.s3z;*.xmz;*.itz;mod.*;*.far;*.mdl;*.okt;*.dmf;*.ptm;*.mdr;*.med;*.ams;*.dbm;*.dsm;*.mid;*.rmi;*.smf;*.bak;*.umx;*.amf;*.psm;*.mt2|" - "All Modules|*.mod;*.nst;*.wow;*.s3m;*.stm;*.669;*.mtm;*.xm;*.it;*.itp;*.mptm;*.ult;*.mdz;*.s3z;*.xmz;*.itz;mod.*;*.far;*.mdl;*.okt;*.dmf;*.ptm;*.mdr;*.med;*.ams;*.dbm;*.dsm;*.mid;*.rmi;*.smf;*.umx;*.amf;*.psm;*.mt2|" + #ifndef NO_MO3_SUPPORT + "All Modules|*.mod;*.nst;*.wow;*.s3m;*.stm;*.669;*.mtm;*.xm;*.it;*.itp;*.mptm;*.ult;*.mdz;*.s3z;*.xmz;*.itz;mod.*;*.far;*.mdl;*.okt;*.dmf;*.ptm;*.mdr;*.med;*.ams;*.dbm;*.dsm;*.mid;*.rmi;*.smf;*.umx;*.amf;*.psm;*.mt2;*.mo3|" + "Compressed Modules (*.mdz;*.s3z;*.xmz;*.itz;*.mo3)|*.mdz;*.s3z;*.xmz;*.itz;*.mdr;*.zip;*.rar;*.lha;*.mo3|" + #else + "All Modules|*.mod;*.nst;*.wow;*.s3m;*.stm;*.669;*.mtm;*.xm;*.it;*.itp;*.mptm;*.ult;*.mdz;*.s3z;*.xmz;*.itz;mod.*;*.far;*.mdl;*.okt;*.dmf;*.ptm;*.mdr;*.med;*.ams;*.dbm;*.dsm;*.mid;*.rmi;*.smf;*.umx;*.amf;*.psm;*.mt2|" + "Compressed Modules (*.mdz;*.s3z;*.xmz;*.itz)|*.mdz;*.s3z;*.xmz;*.itz;*.mdr;*.zip;*.rar;*.lha|" + #endif // -! NEW_FEATURE#0023 - "Compressed Modules (*.mdz;*.s3z;*.xmz;*.itz)|*.mdz;*.s3z;*.xmz;*.itz;*.mdr;*.zip;*.rar;*.lha|" "ProTracker Modules (*.mod,*.nst)|*.mod;mod.*;*.mdz;*.nst;*.m15|" "ScreamTracker Modules (*.s3m,*.stm)|*.s3m;*.stm;*.s3z|" "FastTracker Modules (*.xm)|*.xm;*.xmz|" @@ -1677,6 +1682,8 @@ "http://www.surina.net/soundtouch/|" "Hermann Seib for his example VST Host implementation|" "http://www.hermannseib.com/english/vsthost.htm|" + "Ian Luck for UNMO3|" + "http://www.un4seen.com/mo3.html|" "Pel K. Txnder for the scrolling credits control :)|" "http://tinyurl.com/4yze8|" "The people at Modplug forums for crucial contribution|" Modified: trunk/OpenMPT/mptrack/Stdafx.h =================================================================== --- trunk/OpenMPT/mptrack/Stdafx.h 2009-01-23 18:49:52 UTC (rev 247) +++ trunk/OpenMPT/mptrack/Stdafx.h 2009-01-29 20:46:51 UTC (rev 248) @@ -77,6 +77,9 @@ // (HACK) Define to build without VST support; makes build possible without VST SDK. //#define NO_VST + +// Define to build without MO3 support. +//#define NO_MO3_SUPPORT void Log(LPCSTR format,...); Modified: trunk/OpenMPT/mptrack/View_pat.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_pat.cpp 2009-01-23 18:49:52 UTC (rev 247) +++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-01-29 20:46:51 UTC (rev 248) @@ -58,7 +58,7 @@ ON_COMMAND(ID_EDIT_SELECTCOLUMN,OnEditSelectColumn) ON_COMMAND(ID_EDIT_SELECTCOLUMN2,OnSelectCurrentColumn) ON_COMMAND(ID_EDIT_FIND, OnEditFind) - ON_COMMAND(ID_EDIT_FIND, OnEditGoto) + ON_COMMAND(ID_EDIT_GOTO_MENU, OnEditGoto) ON_COMMAND(ID_EDIT_FINDNEXT, OnEditFindNext) ON_COMMAND(ID_EDIT_RECSELECT, OnRecordSelect) // -> CODE#0012 @@ -2409,7 +2409,7 @@ p = pSndFile->Patterns[m_nPattern] + r * pSndFile->m_nChannels + c; // If a note or an instr is present on the row, do the change, if required. // Do not set instr if note and instr are both blank. - if ( (p->note||p->instr) && (p->instr!=nIns) ) { + if ( ((p->note > 0 && p->note < NOTE_NOTECUT) ||p->instr) && (p->instr!=nIns) ) { p->instr = nIns; bModified = TRUE; } Modified: trunk/OpenMPT/mptrack/View_tre.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_tre.cpp 2009-01-23 18:49:52 UTC (rev 247) +++ trunk/OpenMPT/mptrack/View_tre.cpp 2009-01-29 20:46:51 UTC (rev 248) @@ -155,7 +155,7 @@ if (m_pDataTree) { // Create Midi Library - m_hMidiLib = InsertItem("Midi Library", IMAGE_FOLDER, IMAGE_FOLDER, TVI_ROOT, TVI_LAST); + m_hMidiLib = InsertItem("MIDI Library", IMAGE_FOLDER, IMAGE_FOLDER, TVI_ROOT, TVI_LAST); for (UINT iMidGrp=0; iMidGrp<17; iMidGrp++) { m_tiMidiGrp[iMidGrp] = InsertItem(szMidiGroupNames[iMidGrp], IMAGE_FOLDER, IMAGE_FOLDER, m_hMidiLib, TVI_LAST); @@ -2163,8 +2163,8 @@ AppendMenu(hMenu, MF_SEPARATOR, NULL, ""); case MODITEM_HDR_MIDILIB: case MODITEM_HDR_MIDIGROUP: - AppendMenu(hMenu, MF_STRING, ID_IMPORT_MIDILIB, "&Import Midi Library"); - AppendMenu(hMenu, MF_STRING, ID_EXPORT_MIDILIB, "E&xport Midi Library"); + AppendMenu(hMenu, MF_STRING, ID_IMPORT_MIDILIB, "&Import MIDI Library"); + AppendMenu(hMenu, MF_STRING, ID_EXPORT_MIDILIB, "E&xport MIDI Library"); bSep = TRUE; break; Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2009-01-23 18:49:52 UTC (rev 247) +++ trunk/OpenMPT/mptrack/mptrack.rc 2009-01-29 20:46:51 UTC (rev 248) @@ -106,10 +106,10 @@ MENUITEM "Save &As...", ID_FILE_SAVE_AS MENUITEM "Save as &Wave...", ID_FILE_SAVEASWAVE MENUITEM "Save as M&P3...", ID_FILE_SAVEASMP3 - MENUITEM "Export as M&idi...", ID_FILE_SAVEMIDI + MENUITEM "Export as M&IDI...", ID_FILE_SAVEMIDI MENUITEM "Export &unraped...", ID_FILE_SAVECOMPAT MENUITEM SEPARATOR - MENUITEM "Import &midi Library...", ID_IMPORT_MIDILIB + MENUITEM "Import &MIDI Library...", ID_IMPORT_MIDILIB MENUITEM "Add Sound &Bank...", ID_ADD_SOUNDBANK MENUITEM SEPARATOR MENUITEM "Recent File", ID_FILE_MRU_FILE1, GRAYED @@ -122,7 +122,7 @@ MENUITEM "P&lay from start\tF6", ID_PLAYER_PLAYFROMSTART MENUITEM "&Stop\tESC", ID_PLAYER_STOP MENUITEM "P&ause\tF8", ID_PLAYER_PAUSE - MENUITEM "&Midi Record\tF9", ID_MIDI_RECORD + MENUITEM "&MIDI Record\tF9", ID_MIDI_RECORD MENUITEM SEPARATOR MENUITEM "&Estimate song length", ID_ESTIMATESONGLENGTH MENUITEM "Approx. real &BPM", ID_APPROX_BPM @@ -150,6 +150,7 @@ MENUITEM SEPARATOR MENUITEM "&Find\tCtrl+F", ID_EDIT_FIND MENUITEM "Find Next\tF3", ID_EDIT_FINDNEXT + MENUITEM "Go to...", ID_EDIT_GOTO_MENU END POPUP "&View" BEGIN @@ -198,7 +199,7 @@ MENUITEM "The Mod Archive", ID_NETLINK_MODARCHIVE END MENUITEM SEPARATOR - MENUITEM "&About MPTrack...", ID_APP_ABOUT + MENUITEM "&About OpenMPT...", ID_APP_ABOUT END END @@ -473,7 +474,7 @@ WS_VISIBLE COMBOBOX IDC_COMBO2,140,30,120,73,CBS_DROPDOWNLIST | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP - CONTROL "Apply Octave Transpose on external midi keyboard", + CONTROL "Apply Octave Transpose on external MIDI keyboard", IDC_CHECK4,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,55, 185,9 CONTROL "Amplify MIDI velocity",IDC_CHECK3,"Button", @@ -882,11 +883,11 @@ WS_TABSTOP,461,37,62,131,WS_EX_CLIENTEDGE CONTROL "Toolbar1",IDC_TOOLBAR1,"ToolbarWindow32",WS_GROUP | 0x4d,4,4,76,17 - CTEXT "Midi / VSTi Channel",IDC_STATIC,246,116,72,12, + CTEXT "MIDI / VSTi Channel",IDC_STATIC,246,116,72,12, SS_CENTERIMAGE,WS_EX_STATICEDGE - CTEXT "Midi Program",IDC_STATIC,246,134,72,12,SS_CENTERIMAGE, + CTEXT "MIDI Program",IDC_STATIC,246,134,72,12,SS_CENTERIMAGE, WS_EX_STATICEDGE - CTEXT "Midi Bank",IDC_STATIC,245,152,72,12,SS_CENTERIMAGE, + CTEXT "MIDI Bank",IDC_STATIC,245,152,72,12,SS_CENTERIMAGE, WS_EX_STATICEDGE CTEXT "Fade Out",IDC_STATIC,8,53,72,12,SS_CENTERIMAGE, WS_EX_STATICEDGE @@ -915,7 +916,7 @@ CTEXT "Action",IDC_STATIC,246,36,59,13,SS_CENTERIMAGE, WS_EX_STATICEDGE GROUPBOX "New Note Action",IDC_STATIC,240,27,122,59 - GROUPBOX "Plugin / Midi",IDC_STATIC,240,88,216,80 + GROUPBOX "Plugin / MIDI",IDC_STATIC,240,88,216,80 GROUPBOX "Sample Quality",IDC_STATIC,3,118,123,50 CTEXT "Ramping",IDC_STATIC,7,133,39,13,SS_CENTERIMAGE, WS_EX_STATICEDGE @@ -1598,15 +1599,15 @@ IDD_MOD2MIDI DIALOG 0, 0, 247, 87 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU -CAPTION "Midi Conversion Setup" +CAPTION "MIDI Conversion Setup" FONT 8, "MS Sans Serif" BEGIN GROUPBOX "",IDC_STATIC,4,4,184,80 LTEXT "Instrument:",IDC_STATIC,10,12,67,8 COMBOBOX IDC_COMBO1,23,22,158,114,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Midi Channel:",IDC_STATIC,10,39,46,8 - LTEXT "Midi Program / Percussion:",IDC_STATIC,81,39,97,8 + LTEXT "MIDI Channel:",IDC_STATIC,10,39,46,8 + LTEXT "MIDI Program / Percussion:",IDC_STATIC,81,39,97,8 COMBOBOX IDC_COMBO2,10,49,66,114,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBO3,81,49,100,114,CBS_DROPDOWNLIST | WS_VSCROLL | @@ -2466,7 +2467,7 @@ STRINGTABLE BEGIN ID_PATTERN_PLAYROW "Play current row\nPlay Row" - ID_IMPORT_MIDILIB "Defines the default midi library used when importing midi files" + ID_IMPORT_MIDILIB "Defines the default MIDI library used when importing MIDI files" ID_CLEANUP_REARRANGE "Rearrange all patterns so that they are sorted in the order list\nRearrange Patterns" END @@ -2476,7 +2477,7 @@ ID_ADD_SOUNDBANK "Add a new DLS sound bank" ID_ORDERLIST_INSERT "Insert a pattern in the order list\nInsert Pattern" ID_ORDERLIST_DELETE "Remove a pattern from the order list\nRemove Pattern" - ID_MIDI_RECORD "Record from an external Midi keyboard\nMidi Record" + ID_MIDI_RECORD "Record from an external MIDI keyboard\nMIDI Record" END STRINGTABLE @@ -2515,7 +2516,7 @@ STRINGTABLE BEGIN ID_SAMPLE_TRIM "Delete everything except the current selection\nTrim Sample" - ID_FILE_SAVEMIDI "Export the current song to a standard midi file" + ID_FILE_SAVEMIDI "Export the current song to a standard MIDI file" ID_NETLINK_FORUMS "Go to the Modplug Central Music Forums" ID_INSTRUMENT_SAMPLEMAP "Edit the sample map" ID_NETLINK_PLUGINS "Go to KVR Audio to download plugins" @@ -2553,6 +2554,11 @@ IDS_OPERATION_FAIL "Operation failed." END +STRINGTABLE +BEGIN + ID_EDIT_GOTO_MENU "Go to row / channel / pattern / order" +END + #endif // English (U.S.) resources ///////////////////////////////////////////////////////////////////////////// @@ -2620,45 +2626,44 @@ // Dialog // -IDD_MIDIPARAMCONTROL DIALOGEX 0, 0, 388, 190 +IDD_MIDIPARAMCONTROL DIALOGEX 0, 0, 392, 202 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_TOOLWINDOW CAPTION "MIDI mapping" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 +FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - DEFPUSHBUTTON "Close",IDOK,334,2,50,14 - LISTBOX IDC_LIST1,3,100,343,82,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | + DEFPUSHBUTTON "Close",IDOK,335,10,50,14 + LISTBOX IDC_LIST1,5,115,325,82,LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP - CONTROL "",IDC_CHECKACTIVE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP, - 29,10,12,10 - COMBOBOX IDC_COMBO_CHANNEL,6,35,36,65,CBS_DROPDOWNLIST | + CONTROL "Active",IDC_CHECKACTIVE,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,15,20,42,10 + COMBOBOX IDC_COMBO_CHANNEL,15,45,36,65,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBO_EVENT,51,35,104,73,CBS_DROPDOWNLIST | + COMBOBOX IDC_COMBO_EVENT,61,45,104,73,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBO_CONTROLLER,160,35,130,90,CBS_DROPDOWNLIST | + COMBOBOX IDC_COMBO_CONTROLLER,171,45,150,90,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Channel",IDC_STATIC,5,25,27,8 - LTEXT "Event",IDC_STATIC,51,25,20,8 - LTEXT "Controller",IDC_STATIC,163,23,32,8 - LTEXT "Plugin",IDC_STATIC,7,50,20,8 - LTEXT "Parameter",IDC_STATIC,164,51,34,8 - COMBOBOX IDC_COMBO_PLUGIN,7,60,139,76,CBS_DROPDOWNLIST | + LTEXT "Channel",IDC_STATIC,15,35,27,8 + LTEXT "Event",IDC_STATIC,61,35,20,8 + LTEXT "Controller",IDC_STATIC,171,35,32,8 + LTEXT "Plugin",IDC_STATIC,15,60,20,8 + LTEXT "Parameter",IDC_STATIC,171,60,34,8 + COMBOBOX IDC_COMBO_PLUGIN,15,70,150,76,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - COMBOBOX IDC_COMBO_PARAM,161,60,149,83,CBS_DROPDOWNLIST | + COMBOBOX IDC_COMBO_PARAM,171,70,149,83,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "MIDI learn",IDC_CHECK_MIDILEARN,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,337,25,47,11 - PUSHBUTTON "Add",IDC_BUTTON_ADD,344,44,40,12 - PUSHBUTTON "Replace",IDC_BUTTON_REPLACE,344,61,40,12 - PUSHBUTTON "Remove",IDC_BUTTON_REMOVE,344,78,40,12 - EDITTEXT IDC_EDIT1,9,77,114,12,ES_AUTOHSCROLL | ES_READONLY - LTEXT "Active",IDC_STATIC,6,10,21,8 + BS_AUTOCHECKBOX | WS_TABSTOP,335,30,47,11 + PUSHBUTTON "Add",IDC_BUTTON_ADD,175,90,45,12 + PUSHBUTTON "Replace",IDC_BUTTON_REPLACE,225,90,45,12 + PUSHBUTTON "Remove",IDC_BUTTON_REMOVE,275,90,45,12 + EDITTEXT IDC_EDIT1,15,90,114,12,ES_AUTOHSCROLL | ES_READONLY CONTROL "Capture",IDC_CHECKCAPTURE,"Button",BS_AUTOCHECKBOX | - BS_LEFTTEXT | WS_TABSTOP,49,9,39,10 - GROUPBOX "",IDC_STATIC,2,2,324,93 - CONTROL "",IDC_SPINMOVEMAPPING,"msctls_updown32",0x0,357,119,17, - 37 + WS_TABSTOP,65,20,39,10 + GROUPBOX "Current mapping",IDC_STATIC,5,5,325,105 + CONTROL "",IDC_SPINMOVEMAPPING,"msctls_updown32",0x0,330,115,11, + 80 END IDD_TUNING DIALOGEX 0, 0, 512, 240 @@ -2730,10 +2735,10 @@ WS_EX_STATICEDGE END -IDD_CHANNELMANAGER DIALOGEX 0, 0, 523, 230 +IDD_CHANNELMANAGER DIALOGEX 0, 0, 523, 231 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU -EXSTYLE WS_EX_TOOLWINDOW | WS_EX_CLIENTEDGE | WS_EX_APPWINDOW +EXSTYLE WS_EX_TOOLWINDOW CAPTION "Channel manager" FONT 8, "MS Shell Dlg", 0, 0, 0x0 BEGIN @@ -2795,7 +2800,7 @@ GROUPBOX "Audio",IDC_STATIC,16,38,182,100 COMBOBOX IDC_COMBO1,21,48,86,30,CBS_DROPDOWN | CBS_SORT | WS_VSCROLL | WS_TABSTOP - GROUPBOX "Midi",IDC_STATIC,219,38,182,100 + GROUPBOX "MIDI",IDC_STATIC,219,38,182,100 LISTBOX IDC_LIST3,21,63,86,68,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP COMBOBOX IDC_COMBO2,109,48,86,30,CBS_DROPDOWN | CBS_SORT | @@ -2834,9 +2839,9 @@ BEGIN IDD_MIDIPARAMCONTROL, DIALOG BEGIN - RIGHTMARGIN, 384 + RIGHTMARGIN, 388 TOPMARGIN, 2 - BOTTOMMARGIN, 189 + BOTTOMMARGIN, 201 END IDD_TUNING, DIALOG Modified: trunk/OpenMPT/mptrack/mptrack.vcproj =================================================================== --- trunk/OpenMPT/mptrack/mptrack.vcproj 2009-01-23 18:49:52 UTC (rev 247) +++ trunk/OpenMPT/mptrack/mptrack.vcproj 2009-01-29 20:46:51 UTC (rev 248) @@ -289,6 +289,9 @@ RelativePath="..\soundlib\load_mid.cpp"> </File> <File + RelativePath="..\soundlib\Load_mo3.cpp"> + </File> + <File RelativePath="..\soundlib\Load_mod.cpp"> </File> <File Modified: trunk/OpenMPT/mptrack/resource.h =================================================================== --- trunk/OpenMPT/mptrack/resource.h 2009-01-23 18:49:52 UTC (rev 247) +++ trunk/OpenMPT/mptrack/resource.h 2009-01-29 20:46:51 UTC (rev 248) @@ -1050,6 +1050,7 @@ #define ID_NETLINK_OPENMPTWIKI_GERMAN 59213 #define ID_NETLINK_MODARCHIVE 59214 #define ID_PATTERN_DUPLICATECHANNEL 59216 +#define ID_EDIT_GOTO_MENU 59220 // Next default values for new objects // @@ -1057,7 +1058,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 516 -#define _APS_NEXT_COMMAND_VALUE 59217 +#define _APS_NEXT_COMMAND_VALUE 59221 #define _APS_NEXT_CONTROL_VALUE 2341 #define _APS_NEXT_SYMED_VALUE 901 #endif Added: trunk/OpenMPT/soundlib/Load_mo3.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mo3.cpp (rev 0) +++ trunk/OpenMPT/soundlib/Load_mo3.cpp 2009-01-29 20:46:51 UTC (rev 248) @@ -0,0 +1,76 @@ +/* + * This source code is public domain. + * + * Purpose: Load MO3-packed modules using unmo3.dll + * Authors: Johannes Schultz + * OpenMPT devs +*/ + +#include "stdafx.h" +#include "sndfile.h" + + + +// decode a MO3 file (returns the same "exit codes" as UNMO3.EXE, eg. 0=success) +// IN: data/len = MO3 data/len +// OUT: data/len = decoded data/len (if successful) +typedef int (WINAPI * UNMO3_DECODE)(void **data, int *len); +// free the data returned by UNMO3_Decode +typedef void (WINAPI * UNMO3_FREE)(void *data); + + +BOOL CSoundFile::ReadMO3(LPCBYTE lpStream, const DWORD dwMemLength) +//----------------------------------------------------------- +{ + // no valid MO3 file (magic bytes: "MO3") + if(dwMemLength < 3 || lpStream[0] != 'M' || lpStream[1] != 'O' || lpStream[2] != '3') + return FALSE; + +#ifdef NO_MO3_SUPPORT + UNREFERENCED_PARAMETER(dwMemLength); + AfxMessageBox(GetStrI18N(__TEXT("The file appears to be a MO3 file, but this OpenMPT build does not support loading MO3 files."))); + return false; +#else + BOOL b_result = false; // result of trying to load the module, false == fail. + + int iLen = static_cast<int>(dwMemLength); + void ** mo3Stream = (void **)&lpStream; + + // try to load unmo3.dll dynamically. + HMODULE unmo3 = LoadLibrary(_TEXT("unmo3.dll")); + if(unmo3 == NULL) // Didn't succeed. + { + AfxMessageBox(GetStrI18N(_TEXT("Loading MO3 file failed because unmo3.dll could not be loaded.")), MB_ICONINFORMATION); + } + else //case: dll loaded succesfully. + { + UNMO3_DECODE UNMO3_Decode = (UNMO3_DECODE)GetProcAddress(unmo3, "UNMO3_Decode"); + UNMO3_FREE UNMO3_Free = (UNMO3_FREE)GetProcAddress(unmo3, "UNMO3_Free"); + + if(UNMO3_Decode != NULL && UNMO3_Free != NULL) { + if(UNMO3_Decode(mo3Stream, &iLen) == 0) { + /* if decoding was successful, mo3Stream and iLen will keep the new + pointers now. */ + + if(iLen > 0) + { + b_result = true; + if ((!ReadXM((const BYTE *)*mo3Stream, (DWORD)iLen)) + && (!ReadIT((const BYTE *)*mo3Stream, (DWORD)iLen)) + && (!ReadS3M((const BYTE *)*mo3Stream, (DWORD)iLen)) + #ifndef FASTSOUNDLIB + && (!ReadMTM((const BYTE *)*mo3Stream, (DWORD)iLen)) + #endif + && (!ReadMod((const BYTE *)*mo3Stream, (DWORD)iLen))) b_result = false; + } + + UNMO3_Free(*mo3Stream); + } + } + FreeLibrary(unmo3); + } + return b_result; +#endif // NO_MO3_SUPPORT +} + + Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-01-23 18:49:52 UTC (rev 247) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-01-29 20:46:51 UTC (rev 248) @@ -29,7 +29,11 @@ #define UNRAR_SUPPORT #define UNLHA_SUPPORT #define ZIPPED_MOD_SUPPORT -LPCSTR glpszModExtensions = "mod|s3m|xm|it|stm|nst|ult|669|wow|mtm|med|far|mdl|ams|dsm|amf|okt|dmf|ptm|psm|mt2|umx"; +LPCSTR glpszModExtensions = "mod|s3m|xm|it|stm|nst|ult|669|wow|mtm|med|far|mdl|ams|dsm|amf|okt|dmf|ptm|psm|mt2|umx" +#ifndef NO_UNMO3_SUPPORT +"|mo3" +#endif +; //Should there be mptm? #endif // NO_ARCHIVE_SUPPORT #else // NO_COPYRIGHT: EarSaver only loads mod/s3m/xm/it/wav @@ -587,6 +591,7 @@ #endif // MODPLUG_TRACKER #endif #endif // MODPLUG_BASIC_SUPPORT + && (!ReadMO3(lpStream, dwMemLength)) && (!ReadMod(lpStream, dwMemLength))) m_nType = MOD_TYPE_NONE; #ifdef ZIPPED_MOD_SUPPORT if ((!m_lpszSongComments) && (archive.GetComments(FALSE))) Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2009-01-23 18:49:52 UTC (rev 247) +++ trunk/OpenMPT/soundlib/Sndfile.h 2009-01-29 20:46:51 UTC (rev 248) @@ -1067,6 +1067,7 @@ BOOL ReadPSM(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadJ2B(LPCBYTE lpStream, DWORD dwMemLength); BOOL ReadUMX(LPCBYTE lpStream, DWORD dwMemLength); + BOOL ReadMO3(LPCBYTE lpStream, const DWORD dwMemLength); BOOL ReadMID(LPCBYTE lpStream, DWORD dwMemLength); // Save Functions #ifndef MODPLUG_NO_FILESAVE This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2009-03-30 22:41:23
|
Revision: 252 http://modplug.svn.sourceforge.net/modplug/?rev=252&view=rev Author: relabsoluness Date: 2009-03-30 22:41:07 +0000 (Mon, 30 Mar 2009) Log Message: ----------- Instrument tuning related changes: . Creating 'group geometric' was broken. / Return-key won't now close the dialog. / Added index in front of note names. / groupsize and groupratio edits are now enabled with general types. Modified Paths: -------------- trunk/OpenMPT/mptrack/TuningDialog.cpp trunk/OpenMPT/mptrack/TuningDialog.h trunk/OpenMPT/mptrack/tuningRatioMapWnd.cpp trunk/OpenMPT/soundlib/tuningbase.cpp Modified: trunk/OpenMPT/mptrack/TuningDialog.cpp =================================================================== --- trunk/OpenMPT/mptrack/TuningDialog.cpp 2009-03-07 21:24:44 UTC (rev 251) +++ trunk/OpenMPT/mptrack/TuningDialog.cpp 2009-03-30 22:41:07 UTC (rev 252) @@ -273,8 +273,8 @@ } else //case: m_pActiveTuning is of type general. { - m_EditSteps.EnableWindow(false); - m_EditRatioPeriod.EnableWindow(false); + //m_EditSteps.EnableWindow(false); + //m_EditRatioPeriod.EnableWindow(false); } m_EditRatioPeriod.Invalidate(); @@ -1293,6 +1293,17 @@ } +void CTuningDialog::OnOK() +//------------------------ +{ + // Prevent return-key from closing the window. + if(GetKeyState(VK_RETURN) <= -127) + return; + else + CDialog::OnOK(); +} + + //////////////////////////////////////////////////////// //*************** //CTuningTreeCtrl Modified: trunk/OpenMPT/mptrack/TuningDialog.h =================================================================== --- trunk/OpenMPT/mptrack/TuningDialog.h 2009-03-07 21:24:44 UTC (rev 251) +++ trunk/OpenMPT/mptrack/TuningDialog.h 2009-03-30 22:41:07 UTC (rev 252) @@ -321,6 +321,7 @@ void DoErrorExit(); + virtual void OnOK(); //Treectrl context menu functions. public: Modified: trunk/OpenMPT/mptrack/tuningRatioMapWnd.cpp =================================================================== --- trunk/OpenMPT/mptrack/tuningRatioMapWnd.cpp 2009-03-07 21:24:44 UTC (rev 251) +++ trunk/OpenMPT/mptrack/tuningRatioMapWnd.cpp 2009-03-30 22:41:07 UTC (rev 252) @@ -64,9 +64,12 @@ const bool isValidNote = m_pTuning->IsValidNote(noteToDraw); string temp; - if(isValidNote) temp = m_pTuning->GetNoteName(noteToDraw); + if(isValidNote) + { + temp = "(" + Stringify(noteToDraw) + ") " + m_pTuning->GetNoteName(noteToDraw); + } - if(isValidNote && temp.size() < sizeofS) + if(isValidNote && temp.size()+1 < sizeofS) wsprintf(s, "%s", temp.c_str()); else wsprintf(s, "%s", "..."); Modified: trunk/OpenMPT/soundlib/tuningbase.cpp =================================================================== --- trunk/OpenMPT/soundlib/tuningbase.cpp 2009-03-07 21:24:44 UTC (rev 251) +++ trunk/OpenMPT/soundlib/tuningbase.cpp 2009-03-30 22:41:07 UTC (rev 252) @@ -431,7 +431,7 @@ return true; if(m_TuningType == TT_GROUPGEOMETRIC) - return CreateGroupGeometric(s, GetGroupRatio(), GetValidityRange().first); + return CreateGroupGeometric(s, GetGroupRatio(), 0); if(m_TuningType == TT_GEOMETRIC) return CreateGeometric(s, GetGroupRatio()); @@ -448,7 +448,7 @@ return true; if(m_TuningType == TT_GROUPGEOMETRIC) - return CreateGroupGeometric(GetGroupSize(), r, GetValidityRange().first); + return CreateGroupGeometric(GetGroupSize(), r, 0); if(m_TuningType == TT_GEOMETRIC) return CreateGeometric(GetGroupSize(), r); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2009-04-04 20:15:26
|
Revision: 254 http://modplug.svn.sourceforge.net/modplug/?rev=254&view=rev Author: relabsoluness Date: 2009-04-04 20:15:12 +0000 (Sat, 04 Apr 2009) Log Message: ----------- (Patches from Jojo, merged slightly modified) + Sample tab: Can now normalize sample selections. . Envelope view: Middle line will now be drawn in panning and pitch/filter envelopes even if row guidelines are enabled. / PackageTemplate:: Update to DE_jojo-keymap Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_smp.cpp trunk/OpenMPT/mptrack/View_ins.cpp trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-04-04 19:09:48 UTC (rev 253) +++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-04-04 20:15:12 UTC (rev 254) @@ -1037,7 +1037,9 @@ //Default case: Normalize current sample UINT iMinSample = m_nSample, iMaxSample = m_nSample; - + //If only one sample is selected, parts of it may be amplified + UINT iStart = 0, iEnd = 0; + //Shift -> Normalize all samples if(CMainFrame::GetInputHandler()->ShiftPressed()) { @@ -1045,6 +1047,13 @@ if(ans == IDNO) return; iMinSample = 1; iMaxSample = m_pSndFile->m_nSamples; + } else { + SAMPLEVIEWSTATE viewstate; + memset(&viewstate, 0, sizeof(viewstate)); + SendViewMessage(VIEWMSG_SAVESTATE, (LPARAM)&viewstate); + + iStart = viewstate.dwBeginSel; + iEnd = viewstate.dwEndSel; } @@ -1058,13 +1067,26 @@ BOOL bOk = FALSE; MODINSTRUMENT *pins = &m_pSndFile->Ins[iSmp]; + if(iMinSample != iMaxSample) { + //if more than one sample is selected, always amplify the whole sample. + iStart = 0; + iEnd = pins->nLength; + } else { + //one sample: correct the boundaries, if needed + if (iEnd > pins->nLength) iEnd = pins->nLength; + if (iStart > iEnd) iStart = iEnd; + if (iStart == iEnd) { + iStart = 0; + iEnd = pins->nLength; + } + } + if (pins->uFlags & CHN_STEREO) { iStart *= 2; iEnd *= 2; } + if (pins->uFlags & CHN_16BIT) { - UINT len = pins->nLength; signed short *p = (signed short *)pins->pSample; - if (pins->uFlags & CHN_STEREO) len *= 2; int max = 1; - for (UINT i=0; i<len; i++) + for (UINT i = iStart; i < iEnd; i++) { if (p[i] > max) max = p[i]; if (-p[i] > max) max = -p[i]; @@ -1072,7 +1094,7 @@ if (max < 32767) { max++; - for (UINT j=0; j<len; j++) + for (UINT j = iStart; j < iEnd; j++) { int l = p[j]; p[j] = (l << 15) / max; @@ -1081,11 +1103,9 @@ } } else { - UINT len = pins->nLength; signed char *p = (signed char *)pins->pSample; - if (pins->uFlags & CHN_STEREO) len *= 2; int max = 1; - for (UINT i=0; i<len; i++) + for (UINT i = iStart; i < iEnd; i++) { if (p[i] > max) max = p[i]; if (-p[i] > max) max = -p[i]; @@ -1093,7 +1113,7 @@ if (max < 127) { max++; - for (UINT j=0; j<len; j++) + for (UINT j = iStart; j < iEnd; j++) { int l = p[j]; p[j] = (l << 7) / max; Modified: trunk/OpenMPT/mptrack/View_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_ins.cpp 2009-04-04 19:09:48 UTC (rev 253) +++ trunk/OpenMPT/mptrack/View_ins.cpp 2009-04-04 20:15:12 UTC (rev 254) @@ -1268,15 +1268,15 @@ //hdc = pDC->m_hDC; oldpen = m_dcMemMain.SelectObject(CMainFrame::penDarkGray); m_dcMemMain.FillRect(&m_rcClient, CBrush::FromHandle(CMainFrame::brushBlack)); + if (m_bGrid) + { + DrawGrid(&m_dcMemMain, pSndFile->m_nMusicSpeed); + } if (m_nEnv != ENV_VOLUME) { m_dcMemMain.MoveTo(0, ymed); m_dcMemMain.LineTo(m_rcClient.right, ymed); } - if (m_bGrid) - { - DrawGrid(&m_dcMemMain, pSndFile->m_nMusicSpeed); - } m_dcMemMain.SelectObject(CMainFrame::penDarkGray); // Drawing Loop Start/End if (EnvGetLoop()) Modified: trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb =================================================================== --- trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb 2009-04-04 19:09:48 UTC (rev 253) +++ trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb 2009-04-04 20:15:12 UTC (rev 254) @@ -6,6 +6,7 @@ //----( Global Context (0) )------------ 0:1347:2:78:1 //File/New: Ctrl+N (KeyDown) 0:1346:2:79:1 //File/Open: Ctrl+O (KeyDown) +0:1348:2:87:1 //File/Close: Ctrl+W (KeyDown) 0:1349:2:83:1 //File/Save: Ctrl+S (KeyDown) 0:1030:0:116:1 //Play song/Pause song: F5 (KeyDown) 0:1031:0:119:1 //Pause song: F8 (KeyDown) @@ -19,6 +20,7 @@ 0:1361:2:67:1 //Copy: Ctrl+C (KeyDown) 0:1361:2:45:1 //Copy: Ctrl+EINFG (KeyDown) 0:1362:2:86:1 //Paste: Ctrl+V (KeyDown) +0:1363:3:86:1 //Mix Paste: Shift+Ctrl+V (KeyDown) 0:1686:1:86:1 //Mix Paste (old IT Style): Shift+V (KeyDown) 0:1364:2:53:1 //SelectAll: Ctrl+5 (KeyDown) 0:1365:2:70:1 //Find: Ctrl+F (KeyDown) @@ -62,6 +64,7 @@ 2:1049:6:35:1 //Go to last row of last channel: Ctrl+Alt+ENDE (KeyDown) 2:1050:1:16:1 //Selection key: Shift+UMSCHALT (KeyDown) 2:1011:2:76:1 //Select channel / Select all: Ctrl+L (KeyDown) +2:1663:0:145:1 //Toggle follow song: ROLLEN-FESTSTELL (KeyDown) 2:1003:0:13:1 //Quick copy: EINGABE (KeyDown) 2:1004:0:32:5 //Quick paste: LEER (KeyDown|KeyHold) 2:1001:2:32:1 //Enable recording: Ctrl+LEER (KeyDown) @@ -79,10 +82,12 @@ 2:1014:2:74:1 //Interpolate volume: Ctrl+J (KeyDown) 2:1015:2:75:1 //Interpolate effect: Ctrl+K (KeyDown) 2:1016:4:66:1 //Open effect visualizer: Alt+B (KeyDown) +2:1766:2:71:1 //Go to row/channel/...: Ctrl+G (KeyDown) 2:1013:2:73:1 //Apply current instrument: Ctrl+I (KeyDown) 2:1660:4:69:5 //Grow selection: Alt+E (KeyDown|KeyHold) 2:1661:4:68:5 //Shrink selection: Alt+D (KeyDown|KeyHold) 2:1059:2:46:1 //Clear row and step: Ctrl+ENTF (KeyDown) +2:1060:1:46:1 //Clear field and step: Shift+ENTF (KeyDown) 2:1665:0:46:1 //Clear field and step (IT Style): ENTF (KeyDown) 2:1061:0:8:5 //Delete rows: R\xDCCK (KeyDown|KeyHold) 2:1377:2:8:5 //Delete all rows: Ctrl+R\xDCCK (KeyDown|KeyHold) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2009-05-01 14:12:37
|
Revision: 255 http://modplug.svn.sourceforge.net/modplug/?rev=255&view=rev Author: relabsoluness Date: 2009-05-01 14:12:28 +0000 (Fri, 01 May 2009) Log Message: ----------- . Fix to faulty portamento handling on loading AMF (patch copied from libmodplug). . Various string null termination and other validations to load functions. Modified Paths: -------------- trunk/OpenMPT/mptrack/misc_util.h trunk/OpenMPT/soundlib/Dlsbank.cpp trunk/OpenMPT/soundlib/LOAD_AMF.CPP trunk/OpenMPT/soundlib/Load_far.cpp trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_mdl.cpp trunk/OpenMPT/soundlib/Load_med.cpp trunk/OpenMPT/soundlib/Load_mt2.cpp trunk/OpenMPT/soundlib/Load_ult.cpp trunk/OpenMPT/soundlib/Sampleio.cpp Modified: trunk/OpenMPT/mptrack/misc_util.h =================================================================== --- trunk/OpenMPT/mptrack/misc_util.h 2009-04-04 20:15:12 UTC (rev 254) +++ trunk/OpenMPT/mptrack/misc_util.h 2009-05-01 14:12:28 UTC (rev 255) @@ -38,5 +38,14 @@ */ } +// Sets last character to null in given char array. +// Size of the array must be known at compile time. +template <size_t size> +inline void SetNullTerminator(char (&buffer)[size]) +{ + STATIC_ASSERT(size > 0); + buffer[size-1] = 0; +} + #endif Modified: trunk/OpenMPT/soundlib/Dlsbank.cpp =================================================================== --- trunk/OpenMPT/soundlib/Dlsbank.cpp 2009-04-04 20:15:12 UTC (rev 254) +++ trunk/OpenMPT/soundlib/Dlsbank.cpp 2009-05-01 14:12:28 UTC (rev 255) @@ -1592,7 +1592,7 @@ if (pSndFile->m_nType & MOD_TYPE_XM) psmp->uFlags |= CHN_PANNING; } } - if (pins->szName[0]) memcpy(pSndFile->m_szNames[nSample], pins->szName, 32); + if (pins->szName[0]) memcpy(pSndFile->m_szNames[nSample], pins->szName, 31); bOk = TRUE; } FreeWaveForm(pWaveForm); @@ -1672,6 +1672,7 @@ } else { memcpy(penv->name, pins->szName, 32); + SetNullTerminator(penv->name); } int nTranspose = 0; for (UINT iNoteMap=0; iNoteMap<NOTE_MAX; iNoteMap++) Modified: trunk/OpenMPT/soundlib/LOAD_AMF.CPP =================================================================== --- trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2009-04-04 20:15:12 UTC (rev 254) +++ trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2009-05-01 14:12:28 UTC (rev 255) @@ -109,8 +109,10 @@ else param = (param&0x0F)<<4; break; // 0x04: Porta Up/Down - case 0x04: if (param & 0x80) { command = CMD_PORTAMENTOUP; param = -(signed char)param; } - else { command = CMD_PORTAMENTODOWN; } break; + //case 0x04: if (param & 0x80) { command = CMD_PORTAMENTOUP; param = -(signed char)param; } + // else { command = CMD_PORTAMENTODOWN; } break; + case 0x04: if (param & 0x80) { command = CMD_PORTAMENTOUP; param = (-(signed char)param)&0x7F; } + else { command = CMD_PORTAMENTODOWN; } break; // 0x06: Tone Portamento case 0x06: command = CMD_TONEPORTAMENTO; break; // 0x07: Tremor @@ -268,7 +270,7 @@ || (!pfh->numsamples) || (pfh->numsamples > MAX_SAMPLES) || (pfh->numchannels < 4) || (pfh->numchannels > 32)) return FALSE; - memcpy(m_szNames[0], pfh->title, 32); + memcpy(m_szNames[0], pfh->title, 31); dwMemPos = sizeof(AMFFILEHEADER); m_nType = MOD_TYPE_AMF; m_nChannels = pfh->numchannels; @@ -330,7 +332,7 @@ AMFSAMPLE *psh = (AMFSAMPLE *)(lpStream + dwMemPos); dwMemPos += sizeof(AMFSAMPLE); - memcpy(m_szNames[iIns+1], psh->samplename, 32); + memcpy(m_szNames[iIns+1], psh->samplename, 31); memcpy(pins->name, psh->filename, 13); pins->nLength = LittleEndian(psh->length); pins->nC4Speed = LittleEndianW(psh->c2spd); Modified: trunk/OpenMPT/soundlib/Load_far.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_far.cpp 2009-04-04 20:15:12 UTC (rev 254) +++ trunk/OpenMPT/soundlib/Load_far.cpp 2009-05-01 14:12:28 UTC (rev 255) @@ -67,7 +67,7 @@ FARHEADER1 farHeader; memcpy(&farHeader, lpStream, sizeof(FARHEADER1)); FARHEADER1 *pmh1 = &farHeader; - FARHEADER2 *pmh2; + FARHEADER2 *pmh2 = 0; DWORD dwMemPos = sizeof(FARHEADER1); UINT headerlen; BYTE samplemap[8]; @@ -87,7 +87,7 @@ m_nDefaultTempo = 80; m_nDefaultGlobalVolume = 256; - memcpy(m_szNames[0], pmh1->songname, 32); + memcpy(m_szNames[0], pmh1->songname, 31); // Channel Setting for (UINT nchpan=0; nchpan<16; nchpan++) { @@ -124,7 +124,7 @@ if (dwMemPos >= dwMemLength) return TRUE; // byteswap pattern data. - for(uint16 psfix = 256; psfix--;) + for(uint16 psfix = 0; psfix < 256; psfix++) { pmh2->patsiz[psfix] = LittleEndianW( pmh2->patsiz[psfix] ) ; } @@ -249,7 +249,7 @@ const FARSAMPLE *pfs = reinterpret_cast<const FARSAMPLE*>(lpStream + dwMemPos); dwMemPos += sizeof(FARSAMPLE); m_nSamples = ismp + 1; - memcpy(m_szNames[ismp+1], pfs->samplename, 32); + memcpy(m_szNames[ismp+1], pfs->samplename, 31); const DWORD length = LittleEndian( pfs->length ); pins->nLength = length; pins->nLoopStart = LittleEndian(pfs->reppos) ; Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2009-04-04 20:15:12 UTC (rev 254) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-05-01 14:12:28 UTC (rev 255) @@ -600,6 +600,7 @@ // ChnSettings[i].szName memcpy(&ChnSettings[i].szName[0],lpStream+streamPos,len); + SetNullTerminator(ChnSettings[i].szName); streamPos += len; } @@ -647,6 +648,7 @@ for(i=0; i<m_nInstruments; i++){ ASSERT_CAN_READ(len); memcpy(&m_szInstrumentPath[i][0],lpStream+streamPos,len); + SetNullTerminator(m_szInstrumentPath[i]); streamPos += len; } @@ -1008,7 +1010,7 @@ if (m_nChannels < GetModSpecifications().channelsMin) m_nChannels = GetModSpecifications().channelsMin; // Reading Song Message - if ((pifh->special & 0x01) && (pifh->msglength) && (pifh->msgoffset + pifh->msglength < dwMemLength)) + if ((pifh->special & 0x01) && (pifh->msglength) && (pifh->msglength <= dwMemLength) && (pifh->msgoffset < dwMemLength - pifh->msglength)) { m_lpszSongComments = new char[pifh->msglength+1]; if (m_lpszSongComments) @@ -1759,6 +1761,7 @@ memset(&itss, 0, sizeof(itss)); memcpy(itss.filename, psmp->name, 12); memcpy(itss.name, m_szNames[nsmp], 26); + SetNullTerminator(itss.name); itss.id = 0x53504D49; itss.gvl = (BYTE)psmp->nGlobalVol; @@ -2055,6 +2058,7 @@ memset(smpcount, 0, sizeof(smpcount)); memcpy(iti.filename, penv->filename, 12); memcpy(iti.name, penv->name, 26); + SetNullTerminator(iti.name); iti.mbank = penv->wMidiBank; iti.mpr = penv->nMidiProgram; iti.mch = penv->nMidiChannel; @@ -2372,6 +2376,7 @@ memset(&itss, 0, sizeof(itss)); memcpy(itss.filename, psmp->name, 12); memcpy(itss.name, m_szNames[nsmp], 26); + SetNullTerminator(itss.name); itss.id = 0x53504D49; itss.gvl = (BYTE)psmp->nGlobalVol; if (m_nInstruments) @@ -2681,6 +2686,7 @@ memset(smpcount, 0, sizeof(smpcount)); memcpy(iti.filename, penv->filename, 12); memcpy(iti.name, penv->name, 26); + SetNullTerminator(iti.name); iti.mbank = penv->wMidiBank; iti.mpr = penv->nMidiProgram; iti.mch = penv->nMidiChannel; @@ -2988,6 +2994,7 @@ memset(&itss, 0, sizeof(itss)); memcpy(itss.filename, psmp->name, 12); memcpy(itss.name, m_szNames[nsmp], 26); + SetNullTerminator(itss.name); itss.id = 0x53504D49; itss.gvl = (BYTE)psmp->nGlobalVol; if (m_nInstruments) Modified: trunk/OpenMPT/soundlib/Load_mdl.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mdl.cpp 2009-04-04 20:15:12 UTC (rev 254) +++ trunk/OpenMPT/soundlib/Load_mdl.cpp 2009-05-01 14:12:28 UTC (rev 255) @@ -215,7 +215,7 @@ block = *((WORD *)(lpStream+dwMemPos)); blocklen = *((DWORD *)(lpStream+dwMemPos+2)); dwMemPos += 6; - if (dwMemPos + blocklen > dwMemLength) + if (blocklen > dwMemLength - dwMemPos) { if (dwMemPos == 11) return FALSE; break; @@ -228,7 +228,7 @@ Log("infoblock: %d bytes\n", blocklen); #endif pmib = (MDLINFOBLOCK *)(lpStream+dwMemPos); - memcpy(m_szNames[0], pmib->songname, 32); + memcpy(m_szNames[0], pmib->songname, 31); norders = pmib->norders; if (norders > MAX_ORDERS) norders = MAX_ORDERS; m_nRestartPos = pmib->repeatpos; @@ -328,6 +328,7 @@ INSTRUMENTHEADER *penv = Headers[nins]; memset(penv, 0, sizeof(INSTRUMENTHEADER)); memcpy(penv->name, lpStream+dwPos+2, 32); + SetNullTerminator(penv->name); penv->nGlobalVol = 64; penv->nPPC = 5*12; SetDefaultInstrumentValues(penv); @@ -411,7 +412,7 @@ if ((nins >= MAX_SAMPLES) || (!nins)) continue; if (m_nSamples < nins) m_nSamples = nins; MODINSTRUMENT *pins = &Ins[nins]; - memcpy(m_szNames[nins], lpStream+dwPos+1, 32); + memcpy(m_szNames[nins], lpStream+dwPos+1, 31); memcpy(pins->name, lpStream+dwPos+33, 8); const BYTE *p = lpStream+dwPos+41; if (pmsh->version > 0) Modified: trunk/OpenMPT/soundlib/Load_med.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_med.cpp 2009-04-04 20:15:12 UTC (rev 254) +++ trunk/OpenMPT/soundlib/Load_med.cpp 2009-05-01 14:12:28 UTC (rev 255) @@ -699,9 +699,11 @@ UINT annotxt = BigEndian(pmex->annotxt); UINT annolen = BigEndian(pmex->annolen); annolen = min(annolen, MED_MAX_COMMENT_LENGTH); //Thanks to Luigi Auriemma for pointing out an overflow risk - if ((annotxt) && (annolen) && (annolen <= dwMemLength) && (annotxt <= dwMemLength - annolen) ) { + if ((annotxt) && (annolen) && (annolen <= dwMemLength) && (annotxt <= dwMemLength - annolen) ) + { m_lpszSongComments = new char[annolen+1]; - if (m_lpszSongComments) { + if (m_lpszSongComments) + { memcpy(m_lpszSongComments, lpStream+annotxt, annolen); m_lpszSongComments[annolen] = 0; } @@ -709,7 +711,7 @@ // Song Name UINT songname = BigEndian(pmex->songname); UINT songnamelen = BigEndian(pmex->songnamelen); - if ((songname) && (songnamelen) && (songname+songnamelen <= dwMemLength)) + if ((songname) && (songnamelen) && (songname <= dwMemLength) && (songnamelen <= dwMemLength-songname)) { if (songnamelen > 31) songnamelen = 31; memcpy(m_szNames[0], lpStream+songname, songnamelen); @@ -722,14 +724,14 @@ UINT ientries = BigEndianW(pmex->i_ext_entries); UINT ientrysz = BigEndianW(pmex->i_ext_entrsz); - if ((iinfoptr) && (ientrysz < 256) && (iinfoptr + ientries*ientrysz < dwMemLength)) + if ((iinfoptr) && (ientrysz < 256) && (ientries*ientrysz < dwMemLength) && (iinfoptr < dwMemLength - ientries*ientrysz)) { LPCSTR psznames = (LPCSTR)(lpStream + iinfoptr); UINT maxnamelen = ientrysz; - if (maxnamelen > 32) maxnamelen = 32; + if (maxnamelen > 31) maxnamelen = 31; for (UINT i=0; i<ientries; i++) if (i < m_nSamples) { - lstrcpyn(m_szNames[i+1], psznames + i*ientrysz, maxnamelen); + memcpy(m_szNames[i+1], psznames + i*ientrysz, maxnamelen); } } } @@ -742,7 +744,7 @@ { DWORD trknameofs = 0, trknamelen = 0; DWORD trktagofs = BigEndian(ptrktags[i]); - if (trktagofs) + if (trktagofs && (trktagofs <= dwMemLength - 8) ) { while (trktagofs+8 < dwMemLength) { @@ -757,9 +759,10 @@ trktagofs += 8; } if (trknamelen > MAX_CHANNELNAME) trknamelen = MAX_CHANNELNAME; - if ((trknameofs) && (trknameofs + trknamelen < dwMemLength)) + if ((trknameofs) && (trknameofs < dwMemLength - trknamelen)) { - lstrcpyn(ChnSettings[i].szName, (LPCSTR)(lpStream+trknameofs), MAX_CHANNELNAME); + memcpy(ChnSettings[i].szName, (LPCSTR)(lpStream+trknameofs), MAX_CHANNELNAME); + SetNullTerminator(ChnSettings[i].szName); } } } Modified: trunk/OpenMPT/soundlib/Load_mt2.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mt2.cpp 2009-04-04 20:15:12 UTC (rev 254) +++ trunk/OpenMPT/soundlib/Load_mt2.cpp 2009-05-01 14:12:28 UTC (rev 255) @@ -406,6 +406,7 @@ { memset(penv, 0, sizeof(INSTRUMENTHEADER)); memcpy(penv->name, pmi->szName, 32); + SetNullTerminator(penv->name); penv->nGlobalVol = 64; penv->nPan = 128; for (UINT i=0; i<NOTE_MAX; i++) @@ -536,7 +537,7 @@ #endif if (iSmp < MAX_SAMPLES) { - memcpy(m_szNames[iSmp], pms->szName, 32); + memcpy(m_szNames[iSmp], pms->szName, 31); } if (pms->dwDataLen > 0) { Modified: trunk/OpenMPT/soundlib/Load_ult.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_ult.cpp 2009-04-04 20:15:12 UTC (rev 254) +++ trunk/OpenMPT/soundlib/Load_ult.cpp 2009-05-01 14:12:28 UTC (rev 255) @@ -60,7 +60,7 @@ m_nType = MOD_TYPE_ULT; m_nDefaultSpeed = 6; m_nDefaultTempo = 125; - memcpy(m_szNames[0], pmh->songtitle, 32); + memcpy(m_szNames[0], pmh->songtitle, 31); // read songtext dwMemPos = sizeof(ULTHEADER); if ((pmh->reserved) && (dwMemPos + pmh->reserved * 32 < dwMemLength)) @@ -89,7 +89,7 @@ { pus = (ULTSAMPLE *)(lpStream+dwMemPos); MODINSTRUMENT *pins = &Ins[ins]; - memcpy(m_szNames[ins], pus->samplename, 32); + memcpy(m_szNames[ins], pus->samplename, 31); memcpy(pins->name, pus->dosname, 12); pins->nLoopStart = pus->loopstart; pins->nLoopEnd = pus->loopend; Modified: trunk/OpenMPT/soundlib/Sampleio.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sampleio.cpp 2009-04-04 20:15:12 UTC (rev 254) +++ trunk/OpenMPT/soundlib/Sampleio.cpp 2009-05-01 14:12:28 UTC (rev 255) @@ -524,7 +524,7 @@ if ((dwInfoList+d+8+len <= dwFileLength) && (len)) { DWORD dwNameLen = len; - if (dwNameLen > 32) dwNameLen = 32; + if (dwNameLen > 31) dwNameLen = 31; memcpy(m_szNames[nSample], lpMemFile+dwInfoList+d+8, dwNameLen); if (phdr->id_RIFF != 0x46464952) { @@ -560,12 +560,13 @@ LPSTR pszTextEx = (LPSTR)(pxh+1); if (xtrabytes >= 32) { - memcpy(m_szNames[nSample], pszTextEx, 32); + memcpy(m_szNames[nSample], pszTextEx, 31); pszTextEx += 32; xtrabytes -= 32; if (xtrabytes >= 22) { memcpy(pins->name, pszTextEx, 22); + SetNullTerminator(pins->name); xtrabytes -= 22; } } @@ -1875,6 +1876,7 @@ iti->id = 0x49504D49; // "IMPI" memcpy(iti->filename, penv->filename, 12); memcpy(iti->name, penv->name, 26); + SetNullTerminator(iti->name); iti->mpr = penv->nMidiProgram; iti->mch = penv->nMidiChannel; iti->mbank = penv->wMidiBank; //rewbs.MidiBank @@ -2125,7 +2127,7 @@ case IFFID_NAME: { UINT len = dwChunkLen; - if (len > 32) len = 32; + if (len > 31) len = 31; memset(m_szNames[nSample], 0, 32); memcpy(m_szNames[nSample], pChunkData, len); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2009-05-02 20:42:23
|
Revision: 256 http://modplug.svn.sourceforge.net/modplug/?rev=256&view=rev Author: relabsoluness Date: 2009-05-02 20:42:19 +0000 (Sat, 02 May 2009) Log Message: ----------- . (patch from Jojo, merged somewhat modified) Fixes to MOD saving: it should now be possible to create ProTracker compatible MOD files with compatibility export. + Added a few hidable usage tips. . Fix to parameter validation in ReadSample. Modified Paths: -------------- trunk/OpenMPT/mptrack/Ctrl_smp.cpp trunk/OpenMPT/mptrack/MainFrm.cpp trunk/OpenMPT/mptrack/Mainfrm.h trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/dlg_misc.cpp trunk/OpenMPT/mptrack/dlg_misc.h trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/mptrack/resource.h trunk/OpenMPT/soundlib/Load_mod.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-05-01 14:12:28 UTC (rev 255) +++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-05-02 20:42:19 UTC (rev 256) @@ -2242,9 +2242,10 @@ memset(&viewstate, 0, sizeof(viewstate)); SendViewMessage(VIEWMSG_SAVESTATE, (LPARAM)&viewstate); if ((!m_pModDoc) || (!m_pSndFile) || (!m_pSndFile->Ins[m_nSample].pSample)) return; - if( AfxMessageBox(TEXT(GetStrI18N("Apply signed/unsigned conversion(distortion)?\n\n" - "Note: in many cases this increases volume level significantly.")), MB_YESNO|MB_ICONQUESTION) == IDNO ) - return; + + if(m_pModDoc->IsNotePlaying(0, m_nSample, 0) == TRUE) + MsgBoxHidable(ConfirmSignUnsignWhenPlaying); + BeginWaitCursor(); pins = &m_pSndFile->Ins[m_nSample]; dwStart = viewstate.dwBeginSel; Modified: trunk/OpenMPT/mptrack/MainFrm.cpp =================================================================== --- trunk/OpenMPT/mptrack/MainFrm.cpp 2009-05-01 14:12:28 UTC (rev 255) +++ trunk/OpenMPT/mptrack/MainFrm.cpp 2009-05-02 20:42:19 UTC (rev 256) @@ -166,6 +166,8 @@ int CMainFrame::gnPlugWindowHeight = 332; DWORD CMainFrame::gnPlugWindowLast = 0; +uint32 CMainFrame::gnMsgBoxVisiblityFlags = ~0; + CRITICAL_SECTION CMainFrame::m_csAudio; HANDLE CMainFrame::m_hPlayThread = NULL; DWORD CMainFrame::m_dwPlayThreadId = 0; @@ -391,6 +393,7 @@ gnPlugWindowWidth = GetPrivateProfileInt("Display", "PlugSelectWindowWidth", 370, iniFile); gnPlugWindowHeight = GetPrivateProfileInt("Display", "PlugSelectWindowHeight", 332, iniFile); gnPlugWindowLast = GetPrivateProfileDWord("Display", "PlugSelectWindowLast", 0, iniFile); + gnMsgBoxVisiblityFlags = GetPrivateProfileDWord("Display", "MsgBoxVisibilityFlags", ~0, iniFile); CHAR s[16]; for (int ncol=0; ncol<MAX_MODCOLORS; ncol++) { @@ -902,6 +905,7 @@ WritePrivateProfileLong("Display", "PlugSelectWindowWidth", gnPlugWindowWidth, iniFile); WritePrivateProfileLong("Display", "PlugSelectWindowHeight", gnPlugWindowHeight, iniFile); WritePrivateProfileLong("Display", "PlugSelectWindowLast", gnPlugWindowLast, iniFile); + WritePrivateProfileDWord("Display", "MsgBoxVisibilityFlags", gnMsgBoxVisiblityFlags, iniFile); CHAR s[16]; for (int ncol=0; ncol<MAX_MODCOLORS; ncol++) { Modified: trunk/OpenMPT/mptrack/Mainfrm.h =================================================================== --- trunk/OpenMPT/mptrack/Mainfrm.h 2009-05-01 14:12:28 UTC (rev 255) +++ trunk/OpenMPT/mptrack/Mainfrm.h 2009-05-02 20:42:19 UTC (rev 256) @@ -425,6 +425,8 @@ static int gnPlugWindowHeight; static DWORD gnPlugWindowLast; + static uint32 gnMsgBoxVisiblityFlags; + // Midi Input public: static HMIDIIN shMidiIn; Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-05-01 14:12:28 UTC (rev 255) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-05-02 20:42:19 UTC (rev 256) @@ -20,6 +20,12 @@ static char THIS_FILE[] = __FILE__; #endif +const TCHAR* const FileFilterMOD = TEXT("ProTracker Modules (*.mod)|*.mod||"); +const TCHAR* const FileFilterXM = TEXT("FastTracker Modules (*.xm)|*.xm||"); +const TCHAR* const FileFilterS3M = TEXT("ScreamTracker Modules (*.s3m)|*.s3m||"); +const TCHAR* const FileFilterIT = TEXT("Impulse Tracker Modules (*.it)|*.it||"); +const TCHAR* const FileFilterITP = TEXT("Impulse Tracker Projects (*.itp)|*.itp||"); +const TCHAR* const FileFilterMPT = TEXT("OpenMPT Modules (*.mptm)|*.mptm||"); ///////////////////////////////////////////////////////////////////////////// // CModDoc @@ -487,18 +493,19 @@ switch(m_SndFile.GetType()) { case MOD_TYPE_MOD: + MsgBoxHidable(ModCompatibilityExportTip); lpszDefExt = "mod"; - lpszFilter = "ProTracker Modules (*.mod)|*.mod||"; + lpszFilter = FileFilterMOD; strcpy(fext, ".mod"); break; case MOD_TYPE_S3M: lpszDefExt = "s3m"; - lpszFilter = "ScreamTracker Modules (*.s3m)|*.s3m||"; + lpszFilter = FileFilterS3M; strcpy(fext, ".s3m"); break; case MOD_TYPE_XM: lpszDefExt = "xm"; - lpszFilter = "FastTracker Modules (*.xm)|*.xm||"; + lpszFilter = FileFilterXM; strcpy(fext, ".xm"); break; case MOD_TYPE_IT: @@ -509,19 +516,21 @@ // strcpy(fext, ".it"); if(m_SndFile.m_dwSongFlags & SONG_ITPROJECT){ lpszDefExt = "itp"; - lpszFilter = "Impulse Tracker Projects (*.itp)|*.itp||"; + lpszFilter = FileFilterITP; strcpy(fext, ".itp"); } - else{ + else + { + MsgBoxHidable(ItCompatibilityExportTip); lpszDefExt = "it"; - lpszFilter = "Impulse Tracker Modules (*.it)|*.it||"; + lpszFilter = FileFilterIT; strcpy(fext, ".it"); } // -! NEW_FEATURE#0023 break; case MOD_TYPE_MPT: lpszDefExt = "mptm"; - lpszFilter = "OpenMPT Modules (*.mptm)|*.mptm||"; + lpszFilter = FileFilterMPT; strcpy(fext, ".mptm"); break; default: @@ -1561,7 +1570,7 @@ //HACK: This is a quick fix. Needs to be better integrated into player and GUI. void CModDoc::OnFileCompatibilitySave() -//------------------------------- +//------------------------------------- { CHAR path[_MAX_PATH]="", drive[_MAX_DRIVE]=""; CHAR s[_MAX_PATH], fname[_MAX_FNAME]=""; @@ -1571,21 +1580,34 @@ UINT type = m_SndFile.GetType(); if ((!pMainFrm) || (!m_SndFile.GetType())) return; - switch (type) { + switch (type) + { /*case MOD_TYPE_XM: ext = "xm"; pattern = "Fast Tracker Files (*.xm)|*.xm||"; break;*/ + case MOD_TYPE_MOD: + ext = MOD_STD_SPECS.fileExtension; + pattern = FileFilterMOD; + if( AfxMessageBox(GetStrI18N(TEXT( + "Compared to regular MOD save, compatibility export makes " + "small adjustments to the save file in order to make the file compatible with " + "ProTracker. Note that this feature is not complete and the " + "file is not guaranteed to be free of MPT-specific features.\n\n " + "Important: beginning of some samples may be adjusted in the process. Proceed?")), MB_ICONINFORMATION|MB_YESNO) != IDYES + ) + return; + break; case MOD_TYPE_IT: - ext = "it"; - pattern = "Impulse Tracker Files (*.it)|*.it||"; + ext = IT_STD_SPECS.fileExtension; + pattern = FileFilterIT; + ::MessageBox(NULL,"Warning: the exported file will not contain any of MPT's file-format hacks.", "Compatibility export warning.",MB_ICONINFORMATION | MB_OK); break; default: - ::MessageBox(NULL,"Compatibility export is currently only available the IT format.", "Can't do compatibility export.",MB_ICONINFORMATION | MB_OK); + ::MessageBox(NULL,"Compatibility export is currently only available for MOD and IT modules.", "Can't do compatibility export.",MB_ICONINFORMATION | MB_OK); return; } - ::MessageBox(NULL,"Warning: the exported file will not contain any of MPT's file-format hacks.", "Compatibility export warning.",MB_ICONINFORMATION | MB_OK); _splitpath(GetPathName(), drive, path, fname, NULL); strcpy(s, drive); strcat(s, path); @@ -1602,7 +1624,13 @@ if (dlg.DoModal() != IDOK){ return; } - switch (type) { + switch (type) + { + case MOD_TYPE_MOD: + m_SndFile.SaveMod(dlg.GetPathName(), 0, true); + SetModified(); // Compatibility save may adjust samples so set modified... + m_ShowSavedialog = true; // ...and force save dialog to appear when saving. + break; case MOD_TYPE_XM: m_SndFile.SaveCompatXM(dlg.GetPathName()); break; Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp =================================================================== --- trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-05-01 14:12:28 UTC (rev 255) +++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-05-02 20:42:19 UTC (rev 256) @@ -2710,4 +2710,90 @@ CDialog::OnCancel(); } +/////////////////////////////////////////////////////////////////////////////////////// +// Messagebox with 'don't show again'-option. +//=================================== +class CMsgBoxHidable : public CDialog +//=================================== +{ +public: + CMsgBoxHidable(LPCTSTR strMsg, bool checkStatus = true, CWnd* pParent = NULL); + enum { IDD = IDD_MSGBOX_HIDABLE }; + + int m_nCheckStatus; + LPCTSTR m_StrMsg; +protected: + virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support + virtual BOOL OnInitDialog(); +}; + + +struct MsgBoxHidableMessage +//========================= +{ + LPCTSTR strMsg; + uint32 nMask; + bool bDefaultDontShowAgainStatus; // true for don't show again, false for show again. +}; + +const MsgBoxHidableMessage HidableMessages[] = +{ + {TEXT("Tip: To create ProTracker compatible MOD-files, try compatibility export from File-menu."), 1, true}, + {TEXT("Tip: To create IT-files without MPT-specific extensions included, try compatibility export from File-menu."), 1 << 1, true}, + {TEXT("Press OK to apply signed/unsigned conversion\n (note: this often significantly increases volume level)"), 1 << 2, false} +}; + +STATIC_ASSERT(ARRAYELEMCOUNT(HidableMessages) == enMsgBoxHidableMessage_count); + +// Messagebox with 'don't show this again'-checkbox. Uses parameter 'enMsg' +// to get the needed information from message array, and updates the variable that +// controls the show/don't show-flags. +void MsgBoxHidable(enMsgBoxHidableMessage enMsg) +//---------------------------------------------- +{ + // Check whether the message should be shown. + if((CMainFrame::gnMsgBoxVisiblityFlags & HidableMessages[enMsg].nMask) == 0) + return; + + const LPCTSTR strMsg = HidableMessages[enMsg].strMsg; + const uint32 mask = HidableMessages[enMsg].nMask; + const bool defaulCheckStatus = HidableMessages[enMsg].bDefaultDontShowAgainStatus; + + // Show dialog. + CMsgBoxHidable dlg(strMsg, defaulCheckStatus); + dlg.DoModal(); + + // Update visibility flags. + if(dlg.m_nCheckStatus == BST_CHECKED) + CMainFrame::gnMsgBoxVisiblityFlags &= ~mask; + else + CMainFrame::gnMsgBoxVisiblityFlags |= mask; +} + + +CMsgBoxHidable::CMsgBoxHidable(LPCTSTR strMsg, bool checkStatus, CWnd* pParent) + : CDialog(CMsgBoxHidable::IDD, pParent), + m_StrMsg(strMsg), + m_nCheckStatus((checkStatus) ? BST_CHECKED : BST_UNCHECKED) +//---------------------------------------------------------------------------- +{} + +BOOL CMsgBoxHidable::OnInitDialog() +//---------------------------------- +{ + CDialog::OnInitDialog(); + SetDlgItemText(IDC_MESSAGETEXT, m_StrMsg); + SetWindowText(AfxGetAppName()); + return TRUE; +} + +void CMsgBoxHidable::DoDataExchange(CDataExchange* pDX) +//------------------------------------------------------ +{ + CDialog::DoDataExchange(pDX); + DDX_Check(pDX, IDC_DONTSHOWAGAIN, m_nCheckStatus); +} + + + Modified: trunk/OpenMPT/mptrack/dlg_misc.h =================================================================== --- trunk/OpenMPT/mptrack/dlg_misc.h 2009-05-01 14:12:28 UTC (rev 255) +++ trunk/OpenMPT/mptrack/dlg_misc.h 2009-05-02 20:42:19 UTC (rev 256) @@ -493,4 +493,18 @@ }; +///////////////////////////////////////////////////////////////////////// +// Messagebox with 'don't show again'-option. + +// Enums for message entries. See dlg_misc.cpp for the array of entries. +enum enMsgBoxHidableMessage +{ + ModCompatibilityExportTip = 0, + ItCompatibilityExportTip = 1, + ConfirmSignUnsignWhenPlaying = 2, + enMsgBoxHidableMessage_count = 3 +}; + +void MsgBoxHidable(enMsgBoxHidableMessage enMsg); + #endif Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2009-05-01 14:12:28 UTC (rev 255) +++ trunk/OpenMPT/mptrack/mptrack.rc 2009-05-02 20:42:19 UTC (rev 256) @@ -2626,6 +2626,19 @@ // Dialog // +IDD_MSGBOX_HIDABLE DIALOGEX 0, 0, 186, 71 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | + WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,149,50,30,14 + PUSHBUTTON "Cancel",IDCANCEL,111,49,30,14,NOT WS_VISIBLE + CONTROL "Don't show this again.",IDC_DONTSHOWAGAIN,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,7,54,90,10 + LTEXT "Static",IDC_MESSAGETEXT,7,7,172,40 +END + IDD_MIDIPARAMCONTROL DIALOGEX 0, 0, 392, 202 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU @@ -2837,6 +2850,14 @@ #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO BEGIN + IDD_MSGBOX_HIDABLE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 179 + TOPMARGIN, 7 + BOTTOMMARGIN, 64 + END + IDD_MIDIPARAMCONTROL, DIALOG BEGIN RIGHTMARGIN, 388 Modified: trunk/OpenMPT/mptrack/resource.h =================================================================== --- trunk/OpenMPT/mptrack/resource.h 2009-05-01 14:12:28 UTC (rev 255) +++ trunk/OpenMPT/mptrack/resource.h 2009-05-02 20:42:19 UTC (rev 256) @@ -104,6 +104,7 @@ #define IDD_DIALOG3 513 #define IDS_ERR_TUNING_SERIALISATION 514 #define IDD_MIDIPARAMCONTROL 515 +#define IDD_MSGBOX_HIDABLE 516 #define IDC_BUTTON1 1001 #define IDC_BUTTON2 1002 #define IDC_BUTTON3 1003 @@ -825,6 +826,8 @@ #define IDC_EDIT_STRETCHPARAMS 2338 #define IDC_MIDI_MACRO_CONTROL 2339 #define IDC_MIDIPLAYPATTERNONMIDIIN 2340 +#define IDC_DONTSHOWAGAIN 2341 +#define IDC_MESSAGETEXT 2342 #define ID_FILE_NEWMOD 32771 #define ID_FILE_NEWXM 32772 #define ID_FILE_NEWS3M 32773 @@ -1057,9 +1060,9 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 516 +#define _APS_NEXT_RESOURCE_VALUE 517 #define _APS_NEXT_COMMAND_VALUE 59221 -#define _APS_NEXT_CONTROL_VALUE 2341 +#define _APS_NEXT_CONTROL_VALUE 2343 #define _APS_NEXT_SYMED_VALUE 901 #endif #endif Modified: trunk/OpenMPT/soundlib/Load_mod.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mod.cpp 2009-05-01 14:12:28 UTC (rev 255) +++ trunk/OpenMPT/soundlib/Load_mod.cpp 2009-05-02 20:42:19 UTC (rev 256) @@ -373,8 +373,8 @@ #ifndef MODPLUG_NO_FILESAVE #pragma warning(disable:4100) -BOOL CSoundFile::SaveMod(LPCSTR lpszFileName, UINT nPacking) -//---------------------------------------------------------- +BOOL CSoundFile::SaveMod(LPCSTR lpszFileName, UINT nPacking, const bool bCompatibilityExport) +//------------------------------------------------------------------------------------------- { BYTE insmap[32]; UINT inslen[32]; @@ -418,8 +418,11 @@ bTab[25] = pins->nVolume >> 2; bTab[26] = pins->nLoopStart >> 9; bTab[27] = pins->nLoopStart >> 1; - bTab[28] = (pins->nLoopEnd - pins->nLoopStart) >> 9; - bTab[29] = (pins->nLoopEnd - pins->nLoopStart) >> 1; + UINT replen = pins->nLoopEnd - pins->nLoopStart; + if(bCompatibilityExport && replen < 2) // ensure PT will load it properly + replen = 2; + bTab[28] = replen >> 9; + bTab[29] = replen >> 1; fwrite(bTab, 30, 1, f); } // Writing number of patterns @@ -501,6 +504,11 @@ for (UINT ismpd=1; ismpd<=31; ismpd++) if (inslen[ismpd]) { MODINSTRUMENT *pins = &Ins[insmap[ismpd]]; + if(bCompatibilityExport == true) + { + if(pins->nLength > 0) pins->pSample[0] = 0; + if(pins->nLength > 1) pins->pSample[1] = 0; + } UINT flags = RS_PCM8S; #ifndef NO_PACKING if (!(pins->uFlags & (CHN_16BIT|CHN_STEREO))) Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-05-01 14:12:28 UTC (rev 255) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-05-02 20:42:19 UTC (rev 256) @@ -1899,12 +1899,13 @@ UINT CSoundFile::ReadSample(MODINSTRUMENT *pIns, UINT nFlags, LPCSTR lpMemFile, DWORD dwMemLength, const WORD format) //----------------------------------------------------------------------------------------------------------------------- { + if ((!pIns) || (pIns->nLength < 4) || (!lpMemFile)) return 0; + if(pIns->nLength > MAX_SAMPLE_LENGTH) pIns->nLength = MAX_SAMPLE_LENGTH; UINT len = 0, mem = pIns->nLength+6; - if ((!pIns) || (pIns->nLength < 4) || (!lpMemFile)) return 0; pIns->uFlags &= ~(CHN_16BIT|CHN_STEREO); if (nFlags & RSF_16BIT) { Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2009-05-01 14:12:28 UTC (rev 255) +++ trunk/OpenMPT/soundlib/Sndfile.h 2009-05-02 20:42:19 UTC (rev 256) @@ -1074,7 +1074,7 @@ UINT WriteSample(FILE *f, MODINSTRUMENT *pins, UINT nFlags, UINT nMaxLen=0); BOOL SaveXM(LPCSTR lpszFileName, UINT nPacking=0); BOOL SaveS3M(LPCSTR lpszFileName, UINT nPacking=0); - BOOL SaveMod(LPCSTR lpszFileName, UINT nPacking=0); + BOOL SaveMod(LPCSTR lpszFileName, UINT nPacking=0, const bool bCompatibilityExport = false); BOOL SaveIT(LPCSTR lpszFileName, UINT nPacking=0); BOOL SaveCompatIT(LPCSTR lpszFileName); BOOL SaveCompatXM(LPCSTR lpszFileName); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2009-05-09 23:01:43
|
Revision: 257 http://modplug.svn.sourceforge.net/modplug/?rev=257&view=rev Author: relabsoluness Date: 2009-05-09 23:01:26 +0000 (Sat, 09 May 2009) Log Message: ----------- . IT load: Macro config should now be loaded correctly also when loading IT files not made with MPT. . IT compatibility export: tentative fix to hidden last sequence item when opened in IT. . IT compatibility play: tentative fix to vibrato with ramp down waveform. / Misc: Minor changes to load functions. / Misc: Removed tremor effect description. Modified Paths: -------------- trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/soundlib/LOAD_AMF.CPP trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_mdl.cpp trunk/OpenMPT/soundlib/Load_med.cpp trunk/OpenMPT/soundlib/Load_mid.cpp trunk/OpenMPT/soundlib/Load_mt2.cpp trunk/OpenMPT/soundlib/Load_okt.cpp trunk/OpenMPT/soundlib/Load_stm.cpp trunk/OpenMPT/soundlib/Sampleio.cpp trunk/OpenMPT/soundlib/Sndmix.cpp Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-05-02 20:42:19 UTC (rev 256) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-05-09 23:01:26 UTC (rev 257) @@ -2495,12 +2495,6 @@ wsprintf(s, "%dbpm", param); break; - case CMD_TREMOR: - if(param) - wsprintf(s, "ontime %d, offtime %d", param >> 4, param & 0x0F); - else - strcpy(s, "continue"); - break; case CMD_RETRIG: switch(param >> 4) { Modified: trunk/OpenMPT/soundlib/LOAD_AMF.CPP =================================================================== --- trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2009-05-02 20:42:19 UTC (rev 256) +++ trunk/OpenMPT/soundlib/LOAD_AMF.CPP 2009-05-09 23:01:26 UTC (rev 257) @@ -174,7 +174,7 @@ DWORD dwMemPos; if ((!lpStream) || (dwMemLength < 2048)) return FALSE; - if ((!strncmp((LPCTSTR)lpStream, "ASYLUM Music Format V1.0", 25)) && (dwMemLength > 4096)) + if ((!strncmp((LPCSTR)lpStream, "ASYLUM Music Format V1.0", 25)) && (dwMemLength > 4096)) { UINT numorders, numpats, numsamples; @@ -370,7 +370,7 @@ // Store tracks positions BYTE **pTrackData = new BYTE *[realtrackcnt]; memset(pTrackData, 0, sizeof(pTrackData)); - for (UINT iTrack=0; iTrack<realtrackcnt; iTrack++) if (dwMemPos + 3 <= dwMemLength) + for (UINT iTrack=0; iTrack<realtrackcnt; iTrack++) if (dwMemPos <= dwMemLength-3) { UINT nTrkSize = LittleEndianW(*(USHORT *)(lpStream+dwMemPos)); nTrkSize += (UINT)lpStream[dwMemPos+2] << 16; Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2009-05-02 20:42:19 UTC (rev 256) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-05-09 23:01:26 UTC (rev 257) @@ -980,7 +980,7 @@ if (pifh->flags & 0x08) m_dwSongFlags |= SONG_LINEARSLIDES; if (pifh->flags & 0x10) m_dwSongFlags |= SONG_ITOLDEFFECTS; if (pifh->flags & 0x20) m_dwSongFlags |= SONG_ITCOMPATMODE; - if (pifh->flags & 0x80) m_dwSongFlags |= SONG_EMBEDMIDICFG; + if ((pifh->flags & 0x80) || (pifh->special & 0x08)) m_dwSongFlags |= SONG_EMBEDMIDICFG; if (pifh->flags & 0x1000) m_dwSongFlags |= SONG_EXFILTERRANGE; memcpy(m_szNames[0], pifh->songname, 26); m_szNames[0][26] = 0; @@ -1241,7 +1241,7 @@ // Reading Samples m_nSamples = pifh->smpnum; if (m_nSamples >= MAX_SAMPLES) m_nSamples = MAX_SAMPLES-1; - for (UINT nsmp=0; nsmp<pifh->smpnum; nsmp++) if ((smppos[nsmp]) && (smppos[nsmp] + sizeof(ITSAMPLESTRUCT) <= dwMemLength)) + for (UINT nsmp=0; nsmp<pifh->smpnum; nsmp++) if ((smppos[nsmp]) && (smppos[nsmp] <= dwMemLength - sizeof(ITSAMPLESTRUCT))) { lastSampleSize = 0; //ensure lastsamplesize = 0 if last sample is empty, else we'll skip the MPTX stuff. ITSAMPLESTRUCT *pis = (ITSAMPLESTRUCT *)(lpStream+smppos[nsmp]); @@ -1761,7 +1761,6 @@ memset(&itss, 0, sizeof(itss)); memcpy(itss.filename, psmp->name, 12); memcpy(itss.name, m_szNames[nsmp], 26); - SetNullTerminator(itss.name); itss.id = 0x53504D49; itss.gvl = (BYTE)psmp->nGlobalVol; @@ -2058,7 +2057,6 @@ memset(smpcount, 0, sizeof(smpcount)); memcpy(iti.filename, penv->filename, 12); memcpy(iti.name, penv->name, 26); - SetNullTerminator(iti.name); iti.mbank = penv->wMidiBank; iti.mpr = penv->nMidiProgram; iti.mch = penv->nMidiChannel; @@ -2376,7 +2374,6 @@ memset(&itss, 0, sizeof(itss)); memcpy(itss.filename, psmp->name, 12); memcpy(itss.name, m_szNames[nsmp], 26); - SetNullTerminator(itss.name); itss.id = 0x53504D49; itss.gvl = (BYTE)psmp->nGlobalVol; if (m_nInstruments) @@ -2545,6 +2542,10 @@ while (header.ordnum>0 && Order[header.ordnum-1]==0xFF) { header.ordnum--; } + + if(header.ordnum + 1 < MAX_ORDERS) + header.ordnum++; + header.patnum = MAX_PATTERNS; while ((header.patnum > 0) && (!Patterns[header.patnum-1])) { header.patnum--; Modified: trunk/OpenMPT/soundlib/Load_mdl.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mdl.cpp 2009-05-02 20:42:19 UTC (rev 256) +++ trunk/OpenMPT/soundlib/Load_mdl.cpp 2009-05-09 23:01:26 UTC (rev 257) @@ -328,7 +328,6 @@ INSTRUMENTHEADER *penv = Headers[nins]; memset(penv, 0, sizeof(INSTRUMENTHEADER)); memcpy(penv->name, lpStream+dwPos+2, 32); - SetNullTerminator(penv->name); penv->nGlobalVol = 64; penv->nPPC = 5*12; SetDefaultInstrumentValues(penv); @@ -458,7 +457,7 @@ { DWORD dwLen = *((DWORD *)(lpStream+dwPos)); dwPos += 4; - if ((dwPos+dwLen <= dwMemLength) && (dwLen > 4)) + if ( (dwLen <= dwMemLength) && (dwPos <= dwMemLength - dwLen) && (dwLen > 4) ) { flags = (pins->uFlags & CHN_16BIT) ? RS_MDL16 : RS_MDL8; ReadSample(pins, flags, (LPSTR)(lpStream+dwPos), dwLen); Modified: trunk/OpenMPT/soundlib/Load_med.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_med.cpp 2009-05-02 20:42:19 UTC (rev 256) +++ trunk/OpenMPT/soundlib/Load_med.cpp 2009-05-09 23:01:26 UTC (rev 257) @@ -521,7 +521,7 @@ dwBlockArr = BigEndian(pmmh->blockarr); dwSmplArr = BigEndian(pmmh->smplarr); dwExpData = BigEndian(pmmh->expdata); - if ((dwExpData) && (dwExpData+sizeof(MMD0EXP) < dwMemLength)) + if ((dwExpData) && (dwExpData < dwMemLength - sizeof(MMD0EXP))) pmex = (MMD0EXP *)(lpStream+dwExpData); else pmex = NULL; @@ -659,7 +659,7 @@ } UINT pseq = 0; - if ((playseqtable) && (playseqtable + nplayseq*4 < dwMemLength)) + if ((playseqtable) && (playseqtable < dwMemLength) && (nplayseq*4 < dwMemLength - playseqtable)) { pseq = BigEndian(((LPDWORD)(lpStream+playseqtable))[nplayseq]); } @@ -737,7 +737,7 @@ } // Track Names DWORD trackinfo_ofs = BigEndian(pmex->trackinfo_ofs); - if ((trackinfo_ofs) && (trackinfo_ofs + m_nChannels * 4 < dwMemLength)) + if ((trackinfo_ofs) && (trackinfo_ofs < dwMemLength) && (m_nChannels * 4 < dwMemLength - trackinfo_ofs)) { DWORD *ptrktags = (DWORD *)(lpStream + trackinfo_ofs); for (UINT i=0; i<m_nChannels; i++) @@ -866,7 +866,7 @@ { DWORD nameofs = BigEndian(pbi->blockname); UINT namelen = BigEndian(pbi->blocknamelen); - if ((nameofs < dwMemLength) && (nameofs+namelen < dwMemLength)) + if ((nameofs < dwMemLength) && (namelen < dwMemLength - nameofs)) { SetPatternName(iBlk, (LPCSTR)(lpStream+nameofs)); } Modified: trunk/OpenMPT/soundlib/Load_mid.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mid.cpp 2009-05-02 20:42:19 UTC (rev 256) +++ trunk/OpenMPT/soundlib/Load_mid.cpp 2009-05-09 23:01:26 UTC (rev 257) @@ -590,7 +590,7 @@ pmth = (MIDITRACKHEADER *)(lpStream+dwMemPos); if (dwMemPos + 8 >= dwMemLength) break; DWORD len = BigEndian(pmth->len); - if ((pmth->id == 0x6B72544D) && (dwMemPos + 8 + len <= dwMemLength)) + if ((pmth->id == 0x6B72544D) && (len <= dwMemLength - (dwMemPos + 8))) { #ifdef MIDI_DETAILED_LOG Log(" track%d at offset %d len=%d ", itrk, dwMemPos+8, len); Modified: trunk/OpenMPT/soundlib/Load_mt2.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_mt2.cpp 2009-05-02 20:42:19 UTC (rev 256) +++ trunk/OpenMPT/soundlib/Load_mt2.cpp 2009-05-09 23:01:26 UTC (rev 257) @@ -418,7 +418,7 @@ #ifdef MT2DEBUG if (iIns <= pfh->wInstruments) Log(" Instrument #%d at offset %04X: %d bytes\n", iIns, dwMemPos, pmi->dwDataLen); #endif - if (((LONG)pmi->dwDataLen > 0) && (dwMemPos + pmi->dwDataLen + 40 <= dwMemLength)) + if (((LONG)pmi->dwDataLen > 0) && (dwMemPos <= dwMemLength - 40) && (pmi->dwDataLen <= dwMemLength - (dwMemPos + 40))) { InstrMap[iIns-1] = pmi; if (penv) Modified: trunk/OpenMPT/soundlib/Load_okt.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_okt.cpp 2009-05-02 20:42:19 UTC (rev 256) +++ trunk/OpenMPT/soundlib/Load_okt.cpp 2009-05-09 23:01:26 UTC (rev 257) @@ -113,7 +113,7 @@ } // PBOD UINT npat = 0; - while ((dwMemPos+10 < dwMemLength) && (*((DWORD *)(lpStream + dwMemPos)) == 0x444F4250)) + while ((dwMemPos < dwMemLength-10) && (*((DWORD *)(lpStream + dwMemPos)) == 0x444F4250)) { DWORD dwPos = dwMemPos + 10; UINT rows = lpStream[dwMemPos+9]; @@ -189,7 +189,7 @@ } // SBOD UINT nsmp = 1; - while ((dwMemPos+10 < dwMemLength) && (*((DWORD *)(lpStream + dwMemPos)) == 0x444F4253)) + while ((dwMemPos < dwMemLength - 10) && (*((DWORD *)(lpStream + dwMemPos)) == 0x444F4253)) { if (nsmp < MAX_SAMPLES) ReadSample(&Ins[nsmp], RS_PCM8S, (LPSTR)(lpStream+dwMemPos+8), dwMemLength-dwMemPos-8); dwMemPos += BigEndian(*((DWORD *)(lpStream + dwMemPos + 4))) + 8; Modified: trunk/OpenMPT/soundlib/Load_stm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_stm.cpp 2009-05-02 20:42:19 UTC (rev 256) +++ trunk/OpenMPT/soundlib/Load_stm.cpp 2009-05-09 23:01:26 UTC (rev 257) @@ -177,7 +177,7 @@ if (pIns->nLength) { UINT nPos = ((UINT)phdr->sample[nSmp-1].reserved) << 4; - if ((nPos >= sizeof(STMHEADER)) && (nPos+pIns->nLength <= dwMemLength)) dwMemPos = nPos; + if ((nPos >= sizeof(STMHEADER)) && (nPos <= dwMemLength) && (pIns->nLength <= dwMemLength-nPos)) dwMemPos = nPos; if (dwMemPos < dwMemLength) { dwMemPos += ReadSample(pIns, RS_PCM8S, (LPSTR)(lpStream+dwMemPos),dwMemLength-dwMemPos); Modified: trunk/OpenMPT/soundlib/Sampleio.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sampleio.cpp 2009-05-02 20:42:19 UTC (rev 256) +++ trunk/OpenMPT/soundlib/Sampleio.cpp 2009-05-09 23:01:26 UTC (rev 257) @@ -566,7 +566,6 @@ if (xtrabytes >= 22) { memcpy(pins->name, pszTextEx, 22); - SetNullTerminator(pins->name); xtrabytes -= 22; } } Modified: trunk/OpenMPT/soundlib/Sndmix.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndmix.cpp 2009-05-02 20:42:19 UTC (rev 256) +++ trunk/OpenMPT/soundlib/Sndmix.cpp 2009-05-09 23:01:26 UTC (rev 257) @@ -1276,7 +1276,10 @@ switch (pChn->nVibratoType & 0x03) { case 1: - vdelta = ModRampDownTable[vibpos]; + if(GetModFlag(MSF_IT_COMPATIBLE_PLAY) == true) + vdelta = -ModRampDownTable[(vibpos+16) % 64]; + else + vdelta = ModRampDownTable[vibpos]; break; case 2: vdelta = ModSquareTable[vibpos]; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2009-05-30 21:22:03
|
Revision: 259 http://modplug.svn.sourceforge.net/modplug/?rev=259&view=rev Author: relabsoluness Date: 2009-05-30 21:21:35 +0000 (Sat, 30 May 2009) Log Message: ----------- 1.17.02.53 Modified Paths: -------------- trunk/OpenMPT/mptrack/bin/mptrack.exe trunk/OpenMPT/packageTemplate/History.txt trunk/OpenMPT/packageTemplate/SoundTouch/README.html trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb Added Paths: ----------- trunk/OpenMPT/mptrack/bin/OpenMPT_SoundTouch.dll Added: trunk/OpenMPT/mptrack/bin/OpenMPT_SoundTouch.dll =================================================================== (Binary files differ) Property changes on: trunk/OpenMPT/mptrack/bin/OpenMPT_SoundTouch.dll ___________________________________________________________________ Added: svn:mime-type + application/octet-stream Modified: trunk/OpenMPT/mptrack/bin/mptrack.exe =================================================================== (Binary files differ) Modified: trunk/OpenMPT/packageTemplate/History.txt =================================================================== --- trunk/OpenMPT/packageTemplate/History.txt 2009-05-17 14:54:05 UTC (rev 258) +++ trunk/OpenMPT/packageTemplate/History.txt 2009-05-30 21:21:35 UTC (rev 259) @@ -8,15 +8,217 @@ ?: other (tx XYZ): thanks to XYZ for telling us about the bug + +v1.17.02.53 (May 2009, revision 259) +------------------------------------ + +General: + + <jojo> Can now import MO3 files using external library. (rev. 248) + + . <jojo> Song Cleanup: Sample cleanup should no longer remove data after sustain loop end point. (rev. 248) + . <jojo> Misc: When adding channels from song properties, new channels are now initialized properly (bug 1814). (rev. 236) + . <jojo> BPM approximation showed wrong rows per beat in some cases (bug 2532) (rev. 231) + . <jojo> Disabled special handling of '&'-character when drawing texts to various components where the special handling should not take place. (http://lpchip.com/modplug/viewtopic.php?t=1962) (rev. 229) + . <re> File opening: Added a couple of return value checks to reduce the change of crash when opening lots of files (bug 2546) (rev. 239) + + / <jojo> Menu: Goto dialog can now be opened from Edit-menu. (rev. 246) + / <re> Pattern cleanup: Clearing sequence after first '---' item is now optional. (rev. 239) + / <re> When passing MIDI to plug, documents will now be set modified since MIDI data may change parameters. (rev. 243) + +General tab: + / <jojo> General tab: VST volume slider is now disabled for S3M. (rev. 246) + / <jojo> General tab: Initial channel volume controls are now enabled only for IT and MPTM. (rev. 246) + +Pattern tab: + + <jojo> Added descriptions of SBx, S3x, S4x and S5x command parameters to note properties dialog. (rev. 251) + + <jojo> Descriptions to retrigger note command parameters in note properties dialog. (rev. 248) + + <jojo> Ability to start playback with incoming MIDI note (see setup->MIDI) (rev. 246) + + <jojo> Duplicate channel (see channel header context menu). (246) + + <re> MIDI controllers can now be used to input smooth MIDI macro commands to pattern (setup->MIDI). (rev. 240) + + . <re> Undo should now work with chords. (rev. 244) + . <re> When playing with MIDI keyboard, plugins got a constant note velocity, not the actual velocity (bug 2754) (rev. 239) + . <re> Undo fixes (didn't properly handle playback positions/multichannel record, set redundant undo points)(rev 243) + . <re> Param record in plugs GUI wrote commands even when pattern record was off. (rev 243) + . <re> Fixed chord detection when row spacing was enabled. (rev 243) + . <re> Fix to displaying wrong pattern name when using more than 255 patterns (http://lpchip.com/modplug/viewtopic.php?t=2344) (rev. 212) + . <re> Accidental moving when selecting order in margins shouldn't happen anymore. (rev 225) + . <re> Fix to possible crash when using undo after pattern resize (bug introduced in rev. 168) + + / <jojo> When applying "change instrument", won't add instrument number to note off/cut if the note doesn't have instrument already. (rev. 248) + / <re> Default orderlist margin value can now be controlled with "DefaultSequenceMargins" ini-settings under "Pattern Editor" context. (rev 225) + / <jojo & re> Sequence view: Sequence scrolling won't no longer be cut on first '---' item on IT/MPTM/XM. (rev. 237) + / <re> Pattern: The keyboard split 'feature' when entering chords is removed (bug 2790). (rev. 244) + +Sample tab: + + <jojo> Can now normalize sample selections. (rev. 254) + + <jojo> Can now optionally normalize all samples instead of just one (click normalize with shift down) (rev. 249) + + <jojo & re> Status bar now displays offset value at given sample point. (rev. 232) + + <jojo & re> Sample amplify now accepts negative values(inverts sample phase) (request 2219) (rev. 234) + + <jojo & re> Signed/unsigned sample conversion. (rev. 235) + + <re> Added button for phase invert to toolbar. (rev. 235) + + <jojo> Ability to save sample as raw. (rev. 236) + + . <re> Fix to zoom-related crash when loading samples in sample tab. Occurs usually with lengthy samples. (rev. 211) + . <jojo> Playing sample selection didn't work properly in all cases (bug 1700). (rev. 231) + . <jojo> Setting loop points could affect playing of sample even if loop was disabled (bug 1874) (rev. 231) + + / <jojo> Notes from MIDI should now be played like notes from keyboard. (rev. 246) + / <jojo> Play sample button now stops previous note even if mod is playing (bug 1366) (rev. 231) + / <jojo> Sustain loop will now be enabled when setting it to sample selection. (rev. 231) + / <jojo> Sample editing: If possible, use loop points as trim limits if there's no selection chosen. (rev. 230) + / <re> Time stretching is now implemented with SoundTouch library. (rev. 228) + / <re> Disabled pitchshifting/time stretching of 8-bit samples(didn't seem to work). (rev. 228) + +Instrument tab: + . <jojo> Envelope view: Middle line will now be drawn in panning and pitch/filter envelopes even if row guidelines are enabled. (rev. 254) + + / <jojo> Instrument tab: Sample map can now map "No sample". (rev. 236) + / <re> Changed default instrument plug volume command handling from Dry/Wet to none. Also added ini-setting with which one can set the default value used for new instruments. Ini setting is "DefaultPlugVolumeHandling" in [Misc], possible values are 0,1,2. (rev. 238) + +MPTM: + . <re> Pattern cleanup: In some cases sequence wasn't cleaned properly for mptm. (rev. 239) + / <re> Changed pattern/order limit for MPTm from 65000 to 4000. (rev. 212) + Instrument tuning: + + <re> Added letter 'b' to drawable letters. (rev. 217) + . <re> Creating 'group geometric' was broken (perhaps since v. 1.17.02.49) (rev. 252) + . <re> Loading certain old tuning objects didn't work. (rev. 238) + / <re> Notes should now be drawn more clearly when using custom tunings. (rev. 217) + +IT: + . <jojo & re> Macro config should now be loaded correctly also when loading IT files not made with MPT. (rev. 257) + . <jojo & re> Playback fix to vibrato with ramp down waveform in IT compatibility play. (rev. 257) + . <re> When file was saved with compatibility export, the last order was not shown in Impulse Tracker. (rev. 257) + +XM: + . <jojo> Fix to handling a special case of Bxx and Dxx (bug 2769) (rev 241) + +S3M: + . <re> S3M saving: Sequence of length 241-255 should now be cut to length 240 instead of ~16. (rev. 239) + / <re> When loading S3M files which contain Zxx-effects, user is now asked how to process them. (bug 2166) (rev. 233) + / <re> S3M saving: Saved sequence is no longer cut on first '---' item. (rev. 239) + +MOD: + . <jojo & re> Fixes to MOD saving: it should now be possible to create ProTracker compatible MOD files with compatibility export. (rev. 256) + +Package template: + / <jojo> PackageTemplate: Update to DE_jojo-keymap + +Misc: + . <from libmodplug> Fix to faulty portamento handling on loading AMF. + . <various> Lots of smaller bug fixes. + + + +v1.17.02.52 (14 Apr 2008, revision 210) +--------------------------------------- + . <re> Shouldn't need winhttp anymore(at least now that updatecheck is disabled). Dependency caused problems in Win98. + . <re> Fix to faulty plug file existence check(introduced in 1.17.02.51)(http://lpchip.com/modplug/viewtopic.php?t=2255) + . <re> Sound card-options buffer length value validation. + . <re> In .51, muted channels were ignored completely in MIDI export. Now pattern effects are processed in muted channels. + . <re> IT style-playback fix + + +v1.17.02.51 (29 Mar 2008, revision 208) +--------------------------------------- + . <re> Fix to crash when loading VST with long(>32) param name. + . <ma & re> Fix to possible memory corruption problem on handling VST with more than 30 outputs. + - VST with more than 32 outputs might still be handled poorly. + . <re> Fix to possible crash when browsing modules in treeview(http://lpchip.com/modplug/viewtopic.php?t=2222). + . <re> Fix to severe memory leak in the same section as above. + . <re> Fix to mptm not showing in tree view file browser. + . <re> Fix to MIDI drum export (http://lpchip.com/modplug/viewtopic.php?t=2024) + . <re> Fix to possible crash on MIDI export if exporting module with more than 64 channels. + / <re> MIDI export won't anymore export muted channels(http://lpchip.com/modplug/viewtopic.php?t=2017) + . <re> When converting MOD->S3M/IT/MPTM, finetune setting was ignored (http://lpchip.com/modplug/viewtopic.php?t=1706) + . <re> IT compatibility: Fix to not resetting envelopes on new instrument (http://lpchip.com/modplug/viewtopic.php?t=1869) + . <re> IT compatibility: Fix to bidi loop resetting (http://lpchip.com/modplug/viewtopic.php?t=788) + . <re> IT compatibility: Fix to note trigger after note cut(http://lpchip.com/modplug/viewtopic.php?t=2080) + . <re> Mixmode-tooltip in general tab was in some cases shown on unrelated controls (http://lpchip.com/modplug/viewtopic.php?t=2176) + . <re> Pitch/tempo lock was lost on first instrument when opening instrument tab for the first time. (http://lpchip.com/modplug/viewtopic.php?t=1823) + . <re> Verifying buffer length-setting read from INI-file to prevent the impression that it can be set < 10 (http://lpchip.com/modplug/viewtopic.php?t=992) + . <re> Pattern effectdata paste was broken for MOD (probably since .46) (http://lpchip.com/modplug/viewtopic.php?t=1938) + / <re> When loading plug information at startup, checking whether the plug files exist. (http://lpchip.com/modplug/viewtopic.php?t=1367) + . <re> Continuous pattern navigation fixes(http://lpchip.com/modplug/viewtopic.php?t=1960, http://lpchip.com/modplug/viewtopic.php?t=1959) + . <re> Keyboard split related fix (http://lpchip.com/modplug/viewtopic.php?t=1887) + . <re> Releasenode information should now be included when copying instrument envelopes (http://lpchip.com/modplug/viewtopic.php?t=1780) + . <ma> Potential memory corruption bug when loading VSTs + + - <re> Removed buggy rearrange samples (http://lpchip.com/modplug/viewtopic.php?t=2148) + . <re> Fixed MIDI mapping not checking MIDI event, which could cause events like pitch bend to trigger some mapping item. + . <re> Extended song/instrument properties were not always loaded correctly for IT (bug introduced in 1.17.02.50)(http://lpchip.com/modplug/viewtopic.php?p=16335) + . <re> Fix for faulty tabs when switching between modtypes with and without instrumenttab. (http://lpchip.com/modplug/viewtopic.php?t=1614) + . <re> Fix for possible crash on save/load when using more than 64 channels with MPTM. + / <re> Modified flag is not set when sliding tempo/global volume slider for MOD file. + / <re> When setting instrument pan, checking whether instrument samples have set pan enabled and optionally disabling them. + + <re> Unmute all(on transition) shortcutkeys should now work in orderlist context. + / <re> Disabled Set Pan in sample tab for XM. + + <re> Half/double pattern rownumber buttons to pattern properties dialog. + / <re> Show prev/next pattern now shows pattern over +++ orderlist items. + + <re> Channel status in status bar now show channel volume info. + / <re> Disabled setting channel pan for MOD/XM in general view. + + +v1.17.02.50 (26 Jan 2008, revision 198) +--------------------------------------- + / <re> MIDICC bug related compatibility improvement for loading old IT/MPTm files. + + <re> MIDI controller mapping to plug params. + + <re> Ability to take MIDI volume into account when playing notes. + + <re> Ability to pass MIDI to plug. + + <re> Ability to start/continue/stop play with certain MIDI messages (untested) + + <re> Ability to choose how volume commands behave for plugs. + . <re> Fixed sending wrong MIDI message in ::MidiCC. + + + <re> Keyshortcuts for preset navigation jumps in VST editor. + . <re> Default VST editor preset field name validation in the menubar. + + + <re> Added ability to edit various flags in song properties. + . <re> Fix for pattern duplicate for small patterns (http://lpchip.com/modplug/viewtopic.php?t=1747) + . <re> Fixed song properties-menu entry in mainframe(was grayed and didn't show keyshortcut) + . <re> Fixed crash with certain toolbar related ini-settings (http://lpchip.com/modplug/viewtopic.php?t=2033) + . <re> Further fixes to prevent unnotified overwriting of file. + / <re> .bak-files won't now be shown with "All modules" filter when loading modules. + . <re> Show row playtime didn't on certain cases work on first pattern row (http://lpchip.com/modplug/viewtopic.php?t=2044) + . <re> Fix to faulty play with certain instruments without notes in IT compatible playmode (http://lpchip.com/modplug/viewtopic.php?t=2080) + . <re> Pattern number box didn't open pattern properties when using MPTm. (http://lpchip.com/modplug/viewtopic.php?t=2073) + . <re> Fixed wrong MIDI CC names in macro editor. + ./ <re> Setting volume to 0(v00) in pattern didn't necessarily set volume to 0 when using volume random variation for instrument. All other random variation behaviors are changed as well; now the 'swing' is applied directly to channel values instead of using swing addition, and by default the swing effect is reset on new note. (http://lpchip.com/modplug/viewtopic.php?t=2074) + + / <re> MPTm made with this version will be recognized as IT in earlier versions. + / <re> Various validity checks for read data in ITP loading. + + +v1.17.02.49 (17 Nov 2007, revision 194) +--------------------------------------- + + <re> Improved VST preset navigation in VST window. Known problem: doesn't update if preset is changed from VSTs own preset navigation. + + <re> Improvements in IT compatibility playmode. When loading ITs, if file doesn't seem modplug made, then automatically setting IT compatibility playmode. The playmode setting can be toggled in song properties dialog, and the autodetection with an ini setting. + + <re> 'key binding not understood'-messages can be disabled with an ini setting. + . <re> Fixed wrong file version in IT compatibility save. (http://lpchip.com/modplug/viewtopic.php?t=1723) + . <re> Fixed possible unnotified overwriting of file occurring for example when dealing with a new file. (http://lpchip.com/modplug/viewtopic.php?t=1813) + . <re> Fixed broken note preview for certain type of instruments in instrument tab. (http://lpchip.com/modplug/viewtopic.php?t=1996) + . <re> Fixed possible crash on channel mode wav export when a channel has a long name. (http://lpchip.com/modplug/viewtopic.php?t=2005) + . <re> Fixed pattern position indicator jump when clicking VST-box in channel header. (http://lpchip.com/modplug/viewtopic.php?t=2014) + / <re> Custom tuning related + -file format changes + -changed interpretation of finesteps: now zero finesteps means that finesteps are equal to notesteps, previously zero finesteps disabled portamentos etc) + -Pitch slide between notes with portamentos is now specialised also for other tuning types than just geometric(changes behavior). Previously behavior was 'geometric' for all types. + + . <rewbs> Fix pattern search, which could search for the wrong param. Also enable typing of desired param value rather than only selecting from listbox. (http://lpchip.com/modplug/viewtopic.php?t=1799) + . <rewbs> Delay-load winhttp.dll and don't die if it can't be found, e.g. on win98. (http://lpchip.com/modplug/viewtopic.php?t=1778) + . <rewbs> Fix a couple of pixels on D# in the pattern editor small font bitmap. (http://lpchip.com/modplug/viewtopic.php?t=1781) + + <rewbs> Add name filter to plugin selection dialog. Useful when you have hundreds of plugins. + + <Pelya> Allow Window key as a modifier in the keyboard configuration. Disables start menu pop-up when pressing the Win key if and only if it used in the active keyboard configuration. + + <Pelya> Disables NumLock/CapsLock/ScrollLock lamps on keyboard if and only if they are used in the active keyboard configuration. The lamps will blink anyway - can't help it until we start using DirectInput. + v1.17.02.48 - . <Relabs> Fix song cleanup issue (http://lpchip.com/modplug/viewtopic.php?t=1711) - . <Relabs> Pitch/Tempo lock fix (broken in .46 and .47) (http://lpchip.com/modplug/viewtopic.php?t=1646) - / <Relabs> Pattern manager channel reordering behviour changes / fixes. (http://lpchip.com/modplug/viewtopic.php?t=1148) + . <re> Fix song cleanup issue (http://lpchip.com/modplug/viewtopic.php?t=1711) + . <re> Pitch/Tempo lock fix (broken in .46 and .47) (http://lpchip.com/modplug/viewtopic.php?t=1646) + / <re> Pattern manager channel reordering behviour changes / fixes. (http://lpchip.com/modplug/viewtopic.php?t=1148) . <pelya> Fix bad horizontal scrolling in pattern editor when positioning the cursor with the mouse. (http://lpchip.com/modplug/viewtopic.php?t=1650) . <rewbs> Fix odd "play row" behaviour when using 1 tick-per-row (http://lpchip.com/modplug/viewtopic.php?t=1038). . <rewbs> Fix pop due to ramping when song starts with a pattern command that sets a low global volume. (http://lpchip.com/modplug/viewtopic.php?t=523) . <rewbs> Fix occasional colour issues with orderlist (http://lpchip.com/modplug/viewtopic.php?t=867) - . <rewbs> Fix impossible horizontal scrolling in pattern editor when playing with follow song on + . <rewbs> Fix impossible horizontal scrolling in pattern editor when playing with follow song on . <rewbs> Grey out "Trim" option in sample editor context menu if there's no selection. (http://lpchip.com/modplug/viewtopic.php?t=908) v1.17.02.47 @@ -26,54 +228,54 @@ . <rewbs> Fix saturation on old modules (introduced in 1.17.02.46). Loading tracks with no saved mixlevel setting defaults to 'original'. Starting new IT, MPTM, ITP or XM defaults to '117RC3'. Starting new MOD or S3M defaults to 'original'. . <rewbs> Tree view FX list now starts with FX01 instead of FX00. - / <Relabs> Pattern skipping behavior returned to that of .45 + / <re> Pattern skipping behavior returned to that of .45 . <pelya & rewbs> internal: ifdefs for compilation on vs2005 - . <Relabs> internal: VS Edit&Continue fix (gone broken in 'RC3'branch) - / <Relabs> Minor modifications(cleanup of channel state reset code, removed unused orderundo-vector.) + . <re> internal: VS Edit&Continue fix (gone broken in 'RC3'branch) + / <re> Minor modifications(cleanup of channel state reset code, removed unused orderundo-vector.) v1.17.02.46 - + <Relabsoluness> Experimental MPTm format: + + <re> Experimental MPTm format: --> Internally, it is still very close to the IT-based format. --> Order&pattern limit increased to 65000; whole range not tested :) (Note that modeffects such as position jump doesn't cover the whole range unless the #-extension can be used(haven't tested)) - + <Relabsoluness> User definable tuning modes for instruments: + + <re> User definable tuning modes for instruments: --> Only available for MPTm --> Ratio value as well as note name for every key can be assigned invidually; gives rather free hands for experiments. --> Every instrument can have it's own tuning --> Tunings can be saved to file and loaded from file. --> IMPORTANT: When using tunings, behavior of various modcommands such as portamento have been changed, and new behaviors are still to be decided. - + <Relabsoluness> In song properties, option to increase playback compatibility with original Impulse Tracker behavior. Is in no way complete; currently affects only a couple of differences. Many differences are still there. - + <Relabsoluness> Ability to load multiple mods/samples/instruments from corresponding load dialogs. + + <re> In song properties, option to increase playback compatibility with original Impulse Tracker behavior. Is in no way complete; currently affects only a couple of differences. Many differences are still there. + + <re> Ability to load multiple mods/samples/instruments from corresponding load dialogs. --> Known issue: Intermittent failures. - + <Relabsoluness> 32-bit float wav import - . <Relabsoluness> 24/32-bit PCM wav sample import fixed - + <Relabsoluness> Playback control additions: 'Solo on transition' & 'Mute on transition'. Available from pattern view context menu(right click). - + <Relabsoluness> Envelope points can be scaled by a factor through context menu on envelopeview(right click) - + <Relabsoluness> Calculator of playback time (measured from start) at the beginning of any row of any pattern (uses existing modlength calculator). + + <re> 32-bit float wav import + . <re> 24/32-bit PCM wav sample import fixed + + <re> Playback control additions: 'Solo on transition' & 'Mute on transition'. Available from pattern view context menu(right click). + + <re> Envelope points can be scaled by a factor through context menu on envelopeview(right click) + + <re> Calculator of playback time (measured from start) at the beginning of any row of any pattern (uses existing modlength calculator). --> Known limitation: When the row is within pattern loop, doesn't give all possible times. + <rewbs> SCx now sends note-off to VSTis at tick x. + <rewbs> New mixmode (called 1.17RC3): bypass global preamp, force soft panning, provide explicit dB value for sample attenuation. WARNING: this mixmode is subject to change. + <rewbs> Check for updates on startup. To disable, set CheckForUpdates=0 in mptrack.ini. . <rewbs> Plugin list window remembers its position/size even on cancel. . <rewbs> Fix odd window position on very first startup (before mptrack.ini is created). - . <Relabsoluness> When opening instruments, load dialog didn't remember its previous path. - . <Relabsoluness> In general tab, it was possible to give longer modname than the fileformat could save. - . <Relabsoluness> Instruments associates with VSTis no longer also need to be associated to a sample in order to play. - . <Relabsoluness> Trash characters to empty ITP comments should no longer appear. - . <Relabsoluness> Channel state should now be updated correctly when e.g. moving channels through channel manager. - . <Relabsoluness> It should no longer be possible to remove all channels from channel manager. - / <Relabsoluness> Channel states resetting when jumping between orders from orderlist. + . <re> When opening instruments, load dialog didn't remember its previous path. + . <re> In general tab, it was possible to give longer modname than the fileformat could save. + . <re> Instruments associates with VSTis no longer also need to be associated to a sample in order to play. + . <re> Trash characters to empty ITP comments should no longer appear. + . <re> Channel state should now be updated correctly when e.g. moving channels through channel manager. + . <re> It should no longer be possible to remove all channels from channel manager. + / <re> Channel states resetting when jumping between orders from orderlist. --> NOTE: While this fixes a bug (behavior change) introduced in the tuning branch(?), it also changes quite prominent behavior so can annoy people - might need to be modified at some point. - / <Relabsoluness> Added version number to the mainframe title. - / <Relabsoluness> Changed the 'order message' at the bottom bar of the screen "Position x of y" to "Position x of y (x in hex of y in hex)". - / <Relabsoluness> Lots of smaller (internal) changes. + / <re> Added version number to the mainframe title. + / <re> Changed the 'order message' at the bottom bar of the screen "Position x of y" to "Position x of y (x in hex of y in hex)". + / <re> Lots of smaller (internal) changes. v1.17.02.45 - + <Relabsoluness & Alex> "Pitch to tempo lock" instrument setting: define the tempo at which your instrument loops correctly, and it will be pitched automatically to match the song's current tempo. - + <Relabsoluness> Notification when attempting to modify pattern but pattern record is off. - + <Relabsoluness> Orderlist margins: you can define how many slots to keep visible around the active pattern as the orderlist scrolls - . <Relabsoluness> Fixes for various unexpected pattern loop state changes. - . <Relabsoluness> Fixes to IT Style clear. - . <Relabsoluness> Memory management fixes and misc other bug fixes. + + <re & Alex> "Pitch to tempo lock" instrument setting: define the tempo at which your instrument loops correctly, and it will be pitched automatically to match the song's current tempo. + + <re> Notification when attempting to modify pattern but pattern record is off. + + <re> Orderlist margins: you can define how many slots to keep visible around the active pattern as the orderlist scrolls + . <re> Fixes for various unexpected pattern loop state changes. + . <re> Fixes to IT Style clear. + . <re> Memory management fixes and misc other bug fixes. . <rewbs> ITP loading fixed (I broke it in v1.17.02.44) . <rewbs> Time estimation fixed for tracks with pattern break+XParam. . <rewbs> "Last saved with" version number was not always saved correctly - fixed @@ -91,14 +293,6 @@ . <rewbs> Added channel limit check when adding chans from the pattern editor. . <rewbs> Fixed instant crash with SampleTank 2.1. -. v1.17.02.43 - + <rewbs> You can now load up new plugins from anywhere, not just the General tab. Select "Plugin Manager..." from the view menu. This can also be assigned to a global hotkey. - Limitation: currently plugins added to a song in this manner with always be put in the first empty slot. In a future version you'll be able to choose the slot directly from that window. - + <rewbs> "Cleanup Plugins" to remove any plugs that are not associated to a channel and not used by an instrument and not used as an output for any used plugs. - . <rewbs> Fixed channel limits. Should be able to correctly save IT pattern data with up to 127 chans. There's only space for 64 channel headers though (channel names etc..). XMs restricted to 64 chans. - . <rewbs> Added channel limit check when adding chans from the pattern editor. - . <rewbs> Fixed instant crash with SampleTank 2.1. - . v1.17.02.42 + <rewbs> "Compatibility export" in file menu: save as 'plain' IT, without all of OpenMPT's crap. IT only for now (not XM). . <rewbs> Set instrument in pattern editor should work when no note is specified (tx Torvus - http://lpchip.com/modplug/viewtopic.php?t=470) @@ -115,14 +309,14 @@ . v 1.17.02.40 - + <Relabsoluness> Added indicator of currently playing pattern to orderlist. - + <Relabsoluness> 'Loop pattern' and 'follow song' keys should now work when orderlist has focus. + + <re> Added indicator of currently playing pattern to orderlist. + + <re> 'Loop pattern' and 'follow song' keys should now work when orderlist has focus. + <rewbs> Removed registry dependencies. All settings will now be saved to ini file. . <rewbs> Correcly update orderlist position when cycling through patterns - . <Relabsoluness> Fixed orderlist GUI update on ctrl-transition when in patternloop mode - . <Relabsoluness> Moving a channel should now correctly take into account record-channels and pending mutes - . <Relabsoluness> Switching autodelay off in the options now works for note-offs as well. - . <Relabsoluness> Some mod-effects like 'pattern jump' and 'break pattern' no longer conflict with pattern loop toggling. + . <re> Fixed orderlist GUI update on ctrl-transition when in patternloop mode + . <re> Moving a channel should now correctly take into account record-channels and pending mutes + . <re> Switching autodelay off in the options now works for note-offs as well. + . <re> Some mod-effects like 'pattern jump' and 'break pattern' no longer conflict with pattern loop toggling. . <rewbs> Fixed bad capping of random cutoff variation (tx LPChip) . <rewbs> Fixed crash on loading ITP with pattern names (tx Relabsoluness) . <rewbs> Fixed incorrect version number in saved files (tx Relabsoluness) @@ -131,12 +325,12 @@ . v 1.17.02.39 - + <Relabsoluness> Remove and insert channels directly from pattern editor via channel header context menu - + <Relabsoluness> Toggle loop pattern playback mode with a shortcut key and a checkbox above the pattern editor - + <Relabsoluness> The automatic note delays that are inserted when recording notes live are now optional - . <Relabsoluness> Fixed auto note delays so they work with S3Ms too - . <Relabsoluness> Fixes and improvements to displayed instrument name in pattern editor - . <Relabsoluness> Fixes and improvements to instrument swap from context menu + + <re> Remove and insert channels directly from pattern editor via channel header context menu + + <re> Toggle loop pattern playback mode with a shortcut key and a checkbox above the pattern editor + + <re> The automatic note delays that are inserted when recording notes live are now optional + . <re> Fixed auto note delays so they work with S3Ms too + . <re> Fixes and improvements to displayed instrument name in pattern editor + . <re> Fixes and improvements to instrument swap from context menu . <rewbs> Plugins should never cause song to be marked as modified if their GUI is not open (tx LPChip) / <rewbs> Version number in executable properties now correlates with real OpenMPT version number / <rewbs> Restored solo/mute in pattern editor main context menu. @@ -173,17 +367,17 @@ (+ <rewbs> volume commands without notes now send volume MIDI CC to plugs, but as far as I've seen, no plugs seem to respond to it.) . v 1.17.02.35 - + <rewbs & Relabsoluness> Note delay (SDx) is written automatically during "live tracking" if there are no effects already on the existing row. + + <rewbs & re> Note delay (SDx) is written automatically during "live tracking" if there are no effects already on the existing row. + <rewbs> Preliminary parameter value recording should work a bit now with follow song on. Attempts to set correct macro if it exists. Will only overwite \xx. Does not work with certain plugs that don't give idle time back to the host during mouse down (e.g. Albino, Vanguard...), still trying to understand this. Please play with this & give feedback, but don't expect miracles yet. :) . <rewbs> Restored external 0-255 sample panning range with XM. / <rewbs> experimental: muting a channel with a VSTi playing should turn off the active note on that channel. / <rewbs> Midi pitch bend reset on each new note for that instrument's midi channel. . v 1.17.02.34 - + <Relabsoluness> Added dynamic instrument list for Change Instrument item in pattern ctx menu. + + <re> Added dynamic instrument list for Change Instrument item in pattern ctx menu. / <rewbs> Disabled it for users who have opted for the old style context menu in general settings, + other minor change. - + <Relabsoluness> Added "Clear selection" item in pattern ctx menu - / <Relabsoluness> Can now set an instrument value for notes which previously had no attached instruments. + + <re> Added "Clear selection" item in pattern ctx menu + / <re> Can now set an instrument value for notes which previously had no attached instruments. + <rewbs> If you load a track with unrecognized plugins, you'll be prompted to search for the plugs on kvraudio. . <rewbs> Fixed rare crash on playback if playing a song with missing plugins. / <rewbs> Minor code cleanups @@ -703,4 +897,4 @@ Questions/comments/bug reports? ------------------------------- -Visit http://modplug.sourceforge.net/forum. \ No newline at end of file +Visit http://modplug.sourceforge.net/forum. Modified: trunk/OpenMPT/packageTemplate/SoundTouch/README.html =================================================================== --- trunk/OpenMPT/packageTemplate/SoundTouch/README.html 2009-05-17 14:54:05 UTC (rev 258) +++ trunk/OpenMPT/packageTemplate/SoundTouch/README.html 2009-05-30 21:21:35 UTC (rev 259) @@ -14,10 +14,10 @@ SoundTouch readme providing documentation for the time stretching feature.<br> SoundTouch WWW page: http://www.surina.net/soundtouch </h5></font> -<h1>SoundTouch audio processing library v1.3.1 +<h1>SoundTouch audio processing library v1.4.0 </h1> <p class="normal">SoundTouch library Copyright (c) Olli -Parviainen 2002-2006 </p> +Parviainen 2002-2009 </p> <hr> <h2>3. About implementation & Usage tips</h2> <h3>3.3. About algorithms</h3> @@ -40,10 +40,10 @@ sound the default parameter set may result into a sub-optimal result.</p> <p>The time-stretch algorithm default -parameter values are set by these #defines in file "TDStretch.h":</p> +parameter values are set by these #defines in file "TDStretch.h":</p> <blockquote> - <pre>#define DEFAULT_SEQUENCE_MS 82 -#define DEFAULT_SEEKWINDOW_MS 28 + <pre>#define DEFAULT_SEQUENCE_MS AUTOMATIC +#define DEFAULT_SEEKWINDOW_MS AUTOMATIC #define DEFAULT_OVERLAP_MS 12</pre> </blockquote> <p>These parameters affect to the time-stretch @@ -55,13 +55,16 @@ the time-stretch algorithm. Larger values mean fewer sequences are used in processing. In principle a larger value sounds better when slowing down the tempo, but worse when increasing the tempo and vice -versa.<br> +versa. <br> + <br> + By default, this setting value is calculated automatically according to + tempo value.<br> </li> <li><strong>DEFAULT_SEEKWINDOW_MS</strong>: The seeking window default length in milliseconds is for the algorithm that seeks the best possible overlapping location. This determines from how wide a sample "window" the algorithm can use to find an optimal mixing -location when the sound sequences are to be linked back together.<br> +location when the sound sequences are to be linked back together. <br> <br> The bigger this window setting is, the higher the possibility to find a better mixing position becomes, but at the same time large values may @@ -69,6 +72,9 @@ chosen at more uneven intervals. If there's a disturbing artifact that sounds as if a constant frequency was drifting around, try reducing this setting.<br> + <br> + By default, this setting value is calculated automatically according to + tempo value.<br> </li> <li><strong>DEFAULT_OVERLAP_MS</strong>: Overlap length in milliseconds. When the sound sequences are mixed back @@ -82,7 +88,7 @@ <p>Notice that these parameters can also be set during execution time with functions "<strong>TDStretch::setParameters()</strong>" and "<strong>SoundTouch::setSetting()</strong>".</p> -<p>The table below summarizes how the +<p>The table below summaries how the parameters can be adjusted for different applications:</p> <table border="1"> <tbody> @@ -94,9 +100,7 @@ affects...</strong></td> <td valign="top"><strong>Smaller value affects...</strong></td> - <td valign="top"><strong>Music</strong></td> - <td valign="top"><strong>Speech</strong></td> - <td valign="top"><strong>Effect in CPU burden</strong></td> + <td valign="top"><strong>Effect to CPU burden</strong></td> </tr> <tr> <td valign="top"> @@ -110,9 +114,6 @@ <td valign="top">Smaller value might be better for speeding up tempo. Reducing the value accelerates the "echoing" artifact when slowing down the tempo </td> - <td valign="top">Default value usually good</td> - <td valign="top">A smaller value than default -might be better</td> <td valign="top">Increasing the parameter value reduces computation burden</td> </tr> @@ -126,9 +127,6 @@ good mixing position, but may cause a "drifting" artifact</td> <td valign="top">Smaller reduce possibility to find a good mixing position, but reduce the "drifting" artifact.</td> - <td valign="top">Default value usually good, -unless a "drifting" artifact is disturbing.</td> - <td valign="top">Default value usually good</td> <td valign="top">Increasing the parameter value increases computation burden</td> </tr> @@ -141,22 +139,124 @@ <td valign="top"> </td> <td valign="top">If you reduce the "sequence ms" setting, you might wish to try a smaller value.</td> - <td valign="top"> </td> - <td valign="top"> </td> <td valign="top">Increasing the parameter value increases computation burden</td> </tr> </tbody> </table> <hr> -<h2 align="left">6. LICENSE </h2> +<h2>5. Change History</h2> +<h3>5.1. SoundTouch library Change History </h3> + +<p><strong>1.4.0:</strong></p> +<ul> +<li>Improved sound quality by automatic calculation of time stretch algorithm + processing parameters according to tempo setting</li> +<li>Moved BPM detection routines from SoundStretch application into SoundTouch + library</li> +<li>Bugfixes: Usage of uninitialied variables, GNU build scripts, compiler errors + due to 'const' keyword mismatch.</li> +<li>Source code cleanup</li> + +</ul> + +<p><strong>v1.3.1: +</strong></p> +<ul> +<li>Changed static class declaration to GCC 4.x compiler compatible syntax.</li> +<li>Enabled MMX/SSE-optimized routines also for GCC compilers. Earlier +the MMX/SSE-optimized routines were written in compiler-specific inline +assembler, now these routines are migrated to use compiler intrinsic +syntax which allows compiling the same MMX/SSE-optimized source code with +both Visual C++ and GCC compilers. </li> +<li>Set floating point as the default sample format and added switch to +the GNU configure script for selecting the other sample format.</li> + +</ul> + +<p><strong>v1.3.0: +</strong></p> +<ul> + <li>Fixed tempo routine output duration inaccuracy due to rounding +error </li> + <li>Implemented separate processing routines for integer and +floating arithmetic to allow improvements to floating point routines +(earlier used algorithms mostly optimized for integer arithmetic also +for floating point samples) </li> + <li>Fixed a bug that distorts sound if sample rate changes during the +sound stream </li> + <li>Fixed a memory leak that appeared in MMX/SSE/3DNow! optimized +routines </li> + <li>Reduced redundant code pieces in MMX/SSE/3DNow! optimized +routines vs. the standard C routines.</li> + <li>MMX routine incompatibility with new gcc compiler versions </li> + <li>Other miscellaneous bug fixes </li> +</ul> +<p><strong>v1.2.1: </strong></p> +<ul> + <li>Added automake/autoconf scripts for GNU +platforms (in courtesy of David Durham)</li> + <li>Fixed SCALE overflow bug in rate transposer +routine.</li> + <li>Fixed 64bit address space bugs.</li> + <li>Created a 'soundtouch' namespace for +SAMPLETYPE definitions.</li> +</ul> +<p><strong>v1.2.0: </strong></p> +<ul> + <li>Added support for 32bit floating point sample +data type with SSE/3DNow! optimizations for Win32 platform (SSE/3DNow! optimizations currently not supported in GCC environment)</li> + <li>Replaced 'make-gcc' script for GNU environment +by master Makefile</li> + <li>Added time-stretch routine configurability to +SoundTouch main class</li> + <li>Bugfixes</li> +</ul> +<p><strong>v1.1.1: </strong></p> +<ul> + <li>Moved SoundTouch under lesser GPL license (LGPL). This allows using SoundTouch library in programs that aren't +released under GPL license. </li> + <li>Changed MMX routine organiation so that MMX optimized routines are now implemented in classes that are derived from +the basic classes having the standard non-mmx routines. </li> + <li>MMX routines to support gcc version 3. </li> + <li>Replaced windows makefiles by script using the .dsw files </li> +</ul> +<p><strong>v1.01: </strong></p> +<ul> + <li>"mmx_gcc.cpp": Added "using namespace std" and +removed "return 0" from a function with void return value to fix +compiler errors when compiling the library in Solaris environment. </li> + <li>Moved file "FIFOSampleBuffer.h" to "include" +directory to allow accessing the FIFOSampleBuffer class from external +files. </li> +</ul> +<p><strong>v1.0: </strong></p> +<ul> + <li>Initial release </li> +</ul> +<p> </p> +<hr> +<h2 >6. Acknowledgements </h2> +<p >Kudos for these people who have submitted bugfixed since +SoundTouch v1.3.1: </p> +<ul> + <li>Arthur A</li> + <li>Richard Ash</li> + <li>Stanislav Brabec</li> + <li>Brian Cameron</li> + <li>Justin Frankel</li> + <li>Jason Garland</li> + <li>Takashi Iwai</li> +</ul> +<p >Moral greetings to all other contributors as well!</p> +<hr> +<h2 >7. LICENSE </h2> <p>SoundTouch audio processing library<br> Copyright (c) Olli Parviainen</p> <p>This library is free software; you can redistribute it and/or modify it under the terms of the GNU -Lesser General Public License as published by the Free Software -Foundation; either version 2.1 of the License, or (at your option) -any later version.</p> +Lesser General Public License vesrion 2.1 as published by the Free Software +Foundation.</p> <p>This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A Modified: trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb =================================================================== --- trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb 2009-05-17 14:54:05 UTC (rev 258) +++ trunk/OpenMPT/packageTemplate/extraKeymaps/DE_jojo.mkb 2009-05-30 21:21:35 UTC (rev 259) @@ -8,6 +8,8 @@ 0:1346:2:79:1 //File/Open: Ctrl+O (KeyDown) 0:1348:2:87:1 //File/Close: Ctrl+W (KeyDown) 0:1349:2:83:1 //File/Save: Ctrl+S (KeyDown) +0:1693:0:166:1 //Previous Document: (KeyDown) +0:1694:0:167:1 //Next Document: (KeyDown) 0:1030:0:116:1 //Play song/Pause song: F5 (KeyDown) 0:1031:0:119:1 //Pause song: F8 (KeyDown) 0:1375:0:27:1 //Stop Song: ESC (KeyDown) @@ -194,6 +196,7 @@ 5:1229:0:55:1 //Set volume digit 7: 7 (KeyDown) 5:1229:0:103:1 //Set volume digit 7: 7 (ZEHNERTASTATUR) (KeyDown) 5:1230:0:56:1 //Set volume digit 8: 8 (KeyDown) +5:1230:0:104:1 //Set volume digit 8: 8 (ZEHNERTASTATUR) (KeyDown) 5:1231:0:57:1 //Set volume digit 9: 9 (KeyDown) 5:1231:0:105:1 //Set volume digit 9: 9 (ZEHNERTASTATUR) (KeyDown) 5:1232:0:86:1 //Vol command - volume: V (KeyDown) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2009-06-06 19:11:22
|
Revision: 263 http://modplug.svn.sourceforge.net/modplug/?rev=263&view=rev Author: relabsoluness Date: 2009-06-06 19:11:18 +0000 (Sat, 06 Jun 2009) Log Message: ----------- + IT/MTPM: Channel settings(vol&pan) for channels after 64 will now be saved in the file. . XM/IT/MPTM: Fixed a bug in reading an extension. This broke the extension search after reading that entry, although the affected entry has been the last extension in the write order. ? Minor tweaks. Modified Paths: -------------- trunk/OpenMPT/mptrack/View_gen.cpp trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Sndfile.cpp Modified: trunk/OpenMPT/mptrack/View_gen.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_gen.cpp 2009-06-06 18:49:52 UTC (rev 262) +++ trunk/OpenMPT/mptrack/View_gen.cpp 2009-06-06 19:11:18 UTC (rev 263) @@ -656,13 +656,14 @@ pModDoc = GetDocument(); nChn = m_nActiveTab * 4; - if ((pModDoc) && (!IsLocked()) && (nChn < 64)) + if ((pModDoc) && (!IsLocked()) && (nChn < MAX_BASECHANNELS)) { BOOL bUpdate = FALSE; short int pos; LockControls(); - for (UINT iCh=0; iCh<4; iCh++) + const UINT nLoopLimit = pModDoc->GetSoundFile()->GetNumChannels() - nChn; + for (UINT iCh=0; iCh<nLoopLimit; iCh++) { // Volume sliders pos = (short int)m_sbVolume[iCh].GetPos(); Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2009-06-06 18:49:52 UTC (rev 262) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-06-06 19:11:18 UTC (rev 263) @@ -917,8 +917,8 @@ } // -! NEW_FEATURE#0023 -BOOL CSoundFile::ReadIT(const BYTE *lpStream, const DWORD dwMemLength) -//-------------------------------------------------------------- +BOOL CSoundFile::ReadIT(const LPCBYTE lpStream, const DWORD dwMemLength) +//---------------------------------------------------------------------- { ITFILEHEADER *pifh = (ITFILEHEADER *)lpStream; @@ -3595,6 +3595,23 @@ fwrite(&size, 1, sizeof(__int16), f); fwrite(&m_nChannels, 1, size, f); + if(TypeIsIT_MPT() && m_nChannels > 64) //IT header has room only for 64 channels. Save the + { //settings that do not fit to the header here as an extension. + code = 'ChnS'; + fwrite(&code, 1, sizeof(__int32), f); + size = (m_nChannels - 64)*2; + fwrite(&size, 1, sizeof(__int16), f); + for(UINT ich = 64; ich < m_nChannels; ich++) + { + BYTE panvol[2]; + panvol[0] = ChnSettings[ich].nPan >> 2; + if (ChnSettings[ich].dwFlags & CHN_SURROUND) panvol[0] = 100; + if (ChnSettings[ich].dwFlags & CHN_MUTE) panvol[0] |= 0x80; + panvol[1] = ChnSettings[ich].nVolume; + fwrite(&panvol, sizeof(panvol), 1, f); + } + } + code = 'TM..'; //write m_nTempoMode fwrite(&code, 1, sizeof(__int32), f); size = sizeof(m_nTempoMode); @@ -3675,13 +3692,13 @@ } -void CSoundFile::LoadExtendedSongProperties(const MODTYPE modtype, BYTE*& ptr, const BYTE* lpStream, const size_t searchlimit) +void CSoundFile::LoadExtendedSongProperties(const MODTYPE modtype, BYTE*& ptr, const LPCBYTE lpStream, const size_t searchlimit) //-------------------------------------------------- { int32 code = 0; int16 size = 0; ptr += sizeof(int32); // jump extension header code - while( (DWORD)(ptr + 6 - lpStream) <= searchlimit ) //Loop until given limit. + while( (DWORD)((ptr + 6) - lpStream) <= searchlimit ) //Loop until given limit. { code = (*((__int32 *)ptr)); // read field code ptr += sizeof(__int32); // jump field code @@ -3708,15 +3725,27 @@ if(DWORD(ptr - lpStream + DWORD(size)) > searchlimit) MessageBox(NULL, "Error: Bad MIMA datasizefield", NULL, MB_ICONERROR); else + GetMIDIMapper().Unserialize(ptr, size); + break; + case 'ChnS': + if( ((ptr - lpStream) + DWORD(size) <= searchlimit) && (size <= 63*2) && (size % 2 == 0) ) { - GetMIDIMapper().Unserialize(ptr, size); - ptr += size; + const BYTE* pData = ptr; + for(__int16 i = 0; i<size/2; i++, pData += 2) if(pData[0] != 0xFF) + { + ChnSettings[i+64].nVolume = pData[1]; + ChnSettings[i+64].nPan = 128; + if (pData[0] & 0x80) ChnSettings[i+64].dwFlags |= CHN_MUTE; + const UINT n = pData[0] & 0x7F; + if (n <= 64) ChnSettings[i+64].nPan = n << 2; + if (n == 100) ChnSettings[i+64].dwFlags |= CHN_SURROUND; + } } break; } - if (fadr != NULL && ptr - lpStream + DWORD(size) <= searchlimit) { // if field code recognized + if (fadr != NULL && (ptr - lpStream) + DWORD(size) <= searchlimit) { // if field code recognized memcpy(fadr,ptr,size); // read field data } ptr += size; // jump field data Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2009-06-06 18:49:52 UTC (rev 262) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2009-06-06 19:11:18 UTC (rev 263) @@ -136,6 +136,7 @@ [EXT] means external (not related) to INSTRUMENTHEADER content C... [EXT] nChannels +ChnS [EXT] IT/MPTM: Channel settings for channels 65-127 if needed (doesn't fit to IT header). CS.. nCutSwing CWV. [EXT] dwCreatedWithVersion DCT. nDCT; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2009-06-12 17:32:32
|
Revision: 268 http://modplug.svn.sourceforge.net/modplug/?rev=268&view=rev Author: relabsoluness Date: 2009-06-12 17:32:08 +0000 (Fri, 12 Jun 2009) Log Message: ----------- ? Added validations to song/instrument extension reading and refactored related code. (merged from rev. 267) Modified Paths: -------------- trunk/OpenMPT/mptrack/misc_util.h trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Load_xm.cpp trunk/OpenMPT/soundlib/Sampleio.cpp trunk/OpenMPT/soundlib/Sndfile.h Modified: trunk/OpenMPT/mptrack/misc_util.h =================================================================== --- trunk/OpenMPT/mptrack/misc_util.h 2009-06-12 16:25:54 UTC (rev 267) +++ trunk/OpenMPT/mptrack/misc_util.h 2009-06-12 17:32:08 UTC (rev 268) @@ -42,10 +42,34 @@ // Size of the array must be known at compile time. template <size_t size> inline void SetNullTerminator(char (&buffer)[size]) +//------------------------------------------------- { STATIC_ASSERT(size > 0); buffer[size-1] = 0; } +// Limits 'val' to given range. If 'val' is less than 'lowerLimit', 'val' is set to value 'lowerLimit'. +// Similarly if 'val' is greater than 'upperLimit', 'val' is set to value 'upperLimit'. +// If 'lowerLimit' > 'upperLimit', 'val' won't be modified. +template<class T, class C> +inline void Limit(T& val, const C lowerLimit, const C upperLimit) +//--------------------------------------------------------------- +{ + if(lowerLimit > upperLimit) return; + if(val < lowerLimit) val = lowerLimit; + else if(val > upperLimit) val = upperLimit; +} + + +// Like Limit, but with upperlimit only. +template<class T, class C> +inline void LimitMax(T& val, const C upperLimit) +//---------------------------------------------- +{ + if(val > upperLimit) + val = upperLimit; +} + + #endif Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2009-06-12 16:25:54 UTC (rev 267) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2009-06-12 17:32:08 UTC (rev 268) @@ -847,8 +847,7 @@ // Extra info data __int32 fcode = 0; - __int16 fsize = 0; - BYTE * ptr = (BYTE *)(lpStream + streamPos); + LPCBYTE ptr = lpStream + min(streamPos, dwMemLength); if (streamPos <= dwMemLength - 4) { fcode = (*((__int32 *)ptr)); @@ -863,7 +862,7 @@ i = 1; // parse file - while( ptr + 4 <= (BYTE *)(lpStream + dwMemLength) && i <= m_nInstruments ){ + while( uintptr_t(ptr - lpStream) <= dwMemLength - 4 && i <= m_nInstruments ){ fcode = (*((__int32 *)ptr)); // read field code @@ -876,16 +875,7 @@ default: ptr += sizeof(__int32); // jump field code - if(ptr + 2 > (BYTE *)(lpStream + dwMemLength)) return FALSE; - fsize = (*((__int16 *)ptr)); // read field size - ptr += sizeof(__int16); // jump field size - BYTE * fadr = GetInstrumentHeaderFieldPointer(Headers[i], fcode, fsize); - if(fadr && fcode != 'K[..') // copy field data in instrument's header - { - if(ptr + fsize > (BYTE *)(lpStream + dwMemLength)) return FALSE; - memcpy(fadr,ptr,fsize); // (except for keyboard mapping) - } - ptr += fsize; // jump field + ReadExtendedInstrumentProperty(Headers[i], fcode, ptr, lpStream + dwMemLength); break; } } @@ -893,7 +883,7 @@ //HACK: if we fail on i <= m_nInstruments above, arrive here without having set fcode as appropriate, // hence the code duplication. - if (ptr + 4 <= (BYTE *)(lpStream + dwMemLength)) { + if ( (uintptr_t)(ptr - lpStream) <= dwMemLength - 4 ) { fcode = (*((__int32 *)ptr)); } @@ -1320,55 +1310,18 @@ ITSAMPLESTRUCT *pis = (ITSAMPLESTRUCT *)(lpStream+smppos[pifh->smpnum-1]); dwMemPos = pis->samplepointer + lastSampleSize; - // Get file pointer to match the first byte of extra settings informations __int16 size = 0; - __int32 code = 0; - __int16 size = 0; - BYTE * ptr = NULL; - if(dwMemPos < dwMemLength) { - ptr = (BYTE *)(lpStream + dwMemPos); - code = (*((__int32 *)ptr));; + // Load instrument and song extensions. + if(mptStartPos >= dwMemPos) + { + LPCBYTE ptr = LoadExtendedInstrumentProperties(lpStream + dwMemPos, lpStream + mptStartPos, &interpretModplugmade); + LoadExtendedSongProperties(GetType(), ptr, lpStream, mptStartPos, &interpretModplugmade); } - - // Instrument extensions - if( code == 'MPTX' ){ - interpretModplugmade = true; - ptr += sizeof(__int32); // jump extension header code - while( (DWORD)(ptr - lpStream) < mptStartPos ){ //Loop 'till beginning of end of file/mpt specific looking for inst. extensions - code = (*((__int32 *)ptr)); // read field code - if (code == 'MPTS') { //Reached song extensions, break out of this loop - break; - } - - ptr += sizeof(__int32); // jump field code - size = (*((__int16 *)ptr)); // read field size - ptr += sizeof(__int16); // jump field size - - for(UINT nins=1; nins<=m_nInstruments; nins++){ - if(Headers[nins]){ - // get field's adress in instrument's header - BYTE * fadr = GetInstrumentHeaderFieldPointer(Headers[nins], code, size); - // copy field data in instrument's header (except for keyboard mapping) - if(fadr && code != 'K[..') memcpy(fadr,ptr,size); - // jump field - ptr += size; - } - } - //end rewbs.instroVSTi - } - } // -! NEW_FEATURE#0027 - // Song extensions - if( code == 'MPTS' ) - { - interpretModplugmade = true; - LoadExtendedSongProperties(GetType(), ptr, lpStream, mptStartPos); - } + // Reading Patterns Patterns.ResizeArray(max(MAX_PATTERNS, npatterns)); - - // Reading Patterns for (UINT npat=0; npat<npatterns; npat++) { if ((!patpos[npat]) || ((DWORD)patpos[npat] >= dwMemLength - 4)) @@ -3691,47 +3644,124 @@ return; } +LPCBYTE CSoundFile::LoadExtendedInstrumentProperties(const LPCBYTE pStart, + const LPCBYTE pEnd, + bool* pInterpretMptMade) +//--------------------------------------------------------------------------- +{ + if( pStart == NULL || pEnd <= pStart || uintptr_t(pEnd - pStart) < 4) + return NULL; -void CSoundFile::LoadExtendedSongProperties(const MODTYPE modtype, BYTE*& ptr, const LPCBYTE lpStream, const size_t searchlimit) -//-------------------------------------------------- + int32 code = 0; + int16 size = 0; + LPCBYTE ptr = pStart; + + memcpy(&code, ptr, sizeof(code)); + + if(code != 'MPTX') + return NULL; + + // Found MPTX, interpret the file MPT made. + if(pInterpretMptMade != NULL) + *pInterpretMptMade = true; + + ptr += sizeof(int32); // jump extension header code + while( ptr < pEnd && uintptr_t(pEnd-ptr) >= 4) //Loop 'till beginning of end of file/mpt specific looking for inst. extensions + { + memcpy(&code, ptr, sizeof(code)); // read field code + if (code == 'MPTS') //Reached song extensions, break out of this loop + return ptr; + + ptr += sizeof(code); // jump field code + + if((uintptr_t)(pEnd - ptr) < 2) + return NULL; + + memcpy(&size, ptr, sizeof(size)); // read field size + ptr += sizeof(size); // jump field size + + if(IsValidSizeField(ptr, pEnd, size) == false) + return NULL; + + for(UINT nins=1; nins<=m_nInstruments; nins++) + { + if(Headers[nins]) + ReadInstrumentExtensionField(Headers[nins], ptr, code, size); + } + } + + return NULL; +} + + +void CSoundFile::LoadExtendedSongProperties(const MODTYPE modtype, + LPCBYTE ptr, + const LPCBYTE lpStream, + const size_t searchlimit, + bool* pInterpretMptMade) +//------------------------------------------------------------------- { + if(searchlimit < 6 || ptr == NULL || ptr < lpStream || uintptr_t(ptr - lpStream) > searchlimit - 4) + return; + + const LPCBYTE pEnd = lpStream + searchlimit; + int32 code = 0; int16 size = 0; - ptr += sizeof(int32); // jump extension header code - while( (DWORD)((ptr + 6) - lpStream) <= searchlimit ) //Loop until given limit. + + memcpy(&code, ptr, sizeof(code)); + + if(code != 'MPTS') + return; + + // Found MPTS, interpret the file MPT made. + if(pInterpretMptMade != NULL) + *pInterpretMptMade = true; + + + // Case macros. + #define CASE(id, data) \ + case id: fadr = reinterpret_cast<BYTE*>(&data); nMaxReadCount = min(size, sizeof(data)); break; + #define CASE_NOTXM(id, data) \ + case id: if(modtype != MOD_TYPE_XM) {fadr = reinterpret_cast<BYTE*>(&data); nMaxReadCount = min(size, sizeof(data));} break; + + ptr += sizeof(code); // jump extension header code + while( uintptr_t(ptr - lpStream) <= searchlimit-6 ) //Loop until given limit. { - code = (*((__int32 *)ptr)); // read field code - ptr += sizeof(__int32); // jump field code - size = (*((__int16 *)ptr)); // read field size - if(size < 0) break; - ptr += sizeof(__int16); // jump field size + code = (*((int32 *)ptr)); // read field code + ptr += sizeof(int32); // jump field code + size = (*((int16 *)ptr)); // read field size + ptr += sizeof(int16); // jump field size + if(IsValidSizeField(ptr, pEnd, size) == false) + break; + + size_t nMaxReadCount = 0; BYTE * fadr = NULL; - switch (code) { // interpret field code - case 'DT..': fadr = reinterpret_cast<BYTE*>(&m_nDefaultTempo); break; - case 'RPB.': fadr = reinterpret_cast<BYTE*>(&m_nRowsPerBeat); break; - case 'RPM.': fadr = reinterpret_cast<BYTE*>(&m_nRowsPerMeasure); break; - case 'C...': if(modtype != MOD_TYPE_XM) fadr = reinterpret_cast<BYTE*>(&m_nChannels); break; - case 'TM..': fadr = reinterpret_cast<BYTE*>(&m_nTempoMode); break; - case 'PMM.': fadr = reinterpret_cast<BYTE*>(&m_nMixLevels); break; - case 'CWV.': fadr = reinterpret_cast<BYTE*>(&m_dwCreatedWithVersion); break; - case 'LSWV': fadr = reinterpret_cast<BYTE*>(&m_dwLastSavedWithVersion); break; - case 'SPA.': fadr = reinterpret_cast<BYTE*>(&m_nSamplePreAmp); break; - case 'VSTV': fadr = reinterpret_cast<BYTE*>(&m_nVSTiVolume); break; - case 'DGV.': fadr = reinterpret_cast<BYTE*>(&m_nDefaultGlobalVolume); break; - case 'RP..': if(modtype != MOD_TYPE_XM) fadr = reinterpret_cast<BYTE*>(&m_nRestartPos); break; - case 'MSF.': fadr = reinterpret_cast<BYTE*>(&m_ModFlags); break; - case 'MIMA': - if(DWORD(ptr - lpStream + DWORD(size)) > searchlimit) - MessageBox(NULL, "Error: Bad MIMA datasizefield", NULL, MB_ICONERROR); - else - GetMIDIMapper().Unserialize(ptr, size); - break; + + switch (code) // interpret field code + { + CASE('DT..', m_nDefaultTempo); + CASE('RPB.', m_nRowsPerBeat); + CASE('RPM.', m_nRowsPerMeasure); + CASE_NOTXM('C...', m_nChannels); + CASE('TM..', m_nTempoMode); + CASE('PMM.', m_nMixLevels); + CASE('CWV.', m_dwCreatedWithVersion); + CASE('LSWV', m_dwLastSavedWithVersion); + CASE('SPA.', m_nSamplePreAmp); + CASE('VSTV', m_nVSTiVolume); + CASE('DGV.', m_nDefaultGlobalVolume); + CASE_NOTXM('RP..', m_nRestartPos); + CASE('MSF.', m_ModFlags); + case 'MIMA': GetMIDIMapper().Unserialize(ptr, size); break; case 'ChnS': - if( ((ptr - lpStream) + DWORD(size) <= searchlimit) && (size <= 63*2) && (size % 2 == 0) ) + if( (size <= 63*2) && (size % 2 == 0) ) { const BYTE* pData = ptr; - for(__int16 i = 0; i<size/2; i++, pData += 2) if(pData[0] != 0xFF) + STATIC_ASSERT(ARRAYELEMCOUNT(ChnSettings) >= 64); + const __int16 nLoopLimit = min(size/2, ARRAYELEMCOUNT(ChnSettings) - 64); + for(__int16 i = 0; i<nLoopLimit; i++, pData += 2) if(pData[0] != 0xFF) { ChnSettings[i+64].nVolume = pData[1]; ChnSettings[i+64].nPan = 128; @@ -3745,11 +3775,30 @@ break; } - if (fadr != NULL && (ptr - lpStream) + DWORD(size) <= searchlimit) { // if field code recognized - memcpy(fadr,ptr,size); // read field data - } + if (fadr != NULL) // if field code recognized + memcpy(fadr,ptr,nMaxReadCount); // read field data + ptr += size; // jump field data } + + // Validate read values. + Limit(m_nDefaultTempo, GetModSpecifications().tempoMin, GetModSpecifications().tempoMax); + //m_nRowsPerBeat + //m_nRowsPerMeasure + LimitMax(m_nChannels, GetModSpecifications().channelsMax); + //m_nTempoMode + //m_nMixLevels + //m_dwCreatedWithVersion + //m_dwLastSavedWithVersion + //m_nSamplePreAmp + //m_nVSTiVolume + //m_nDefaultGlobalVolume); + //m_nRestartPos + //m_ModFlags + + + #undef CASE + #undef CASE_NOTXM } Modified: trunk/OpenMPT/soundlib/Load_xm.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_xm.cpp 2009-06-12 16:25:54 UTC (rev 267) +++ trunk/OpenMPT/soundlib/Load_xm.cpp 2009-06-12 17:32:08 UTC (rev 268) @@ -611,54 +611,16 @@ // Leave if no extra instrument settings are available (end of file reached) if(dwMemPos >= dwMemLength) return TRUE; - // Get file pointer to match the first byte of extra settings informations - BYTE * ptr = (BYTE *)(lpStream + dwMemPos); + bool bInterpretMptMade = false; + LPCBYTE ptr = lpStream + dwMemPos; + if(m_nInstruments) + ptr = LoadExtendedInstrumentProperties(ptr, lpStream+dwMemLength, &bInterpretMptMade); - // Seek for supported extended settings header - __int16 size = 0; - __int32 code = (*((__int32 *)ptr)); + LoadExtendedSongProperties(GetType(), ptr, lpStream, dwMemLength, &bInterpretMptMade); - // Instrument extensions - if( code == 'MPTX' && m_nInstruments ){ - ptr += sizeof(__int32); // jump extension header code - while( (DWORD)(ptr - lpStream) < dwMemLength ){ //Loop 'till end of file looking for inst. extensions + if(bInterpretMptMade && m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 17, 2, 50)) + SetModFlag(MSF_MIDICC_BUGEMULATION, true); - code = (*((__int32 *)ptr)); // read field code - if (code == 'MPTS') { //Reached song extensions, break out of this loop - break; - } - - ptr += sizeof(__int32); // jump field code - size = (*((__int16 *)ptr)); // read field size - ptr += sizeof(__int16); // jump field size - - for(UINT nins=1; nins<=m_nInstruments; nins++){ - if(Headers[nins]){ - // get field's adress in instrument's header - BYTE * fadr = GetInstrumentHeaderFieldPointer(Headers[nins], code, size); - // copy field data in instrument's header (except for keyboard mapping) - if(fadr && code != 'K[..') memcpy(fadr,ptr,size); - // jump field - ptr += size; - } - } - //end rewbs.instroVSTi - } - } -// -! NEW_FEATURE#0027 - - // Song extensions - if( code == 'MPTS' ) - { - LoadExtendedSongProperties(MOD_TYPE_XM, ptr, lpStream, dwMemLength); - if(m_dwLastSavedWithVersion < MAKE_VERSION_NUMERIC(1, 17, 2, 50)) - SetModFlag(MSF_MIDICC_BUGEMULATION, true); - } - - - - - return TRUE; } Modified: trunk/OpenMPT/soundlib/Sampleio.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sampleio.cpp 2009-06-12 16:25:54 UTC (rev 267) +++ trunk/OpenMPT/soundlib/Sampleio.cpp 2009-06-12 17:32:08 UTC (rev 268) @@ -1297,28 +1297,8 @@ // Leave if no extra instrument settings are available (end of file reached) if(dwMemPos >= dwFileLength) return TRUE; - // Compute current file pointer position - BYTE * ptr = (BYTE *)(lpMemFile+dwMemPos); + ReadExtendedInstrumentProperties(penv, lpMemFile + dwMemPos, dwFileLength - dwMemPos); - // Seek for supported extended settings header - if( (*((__int32 *)ptr)) == 'MPTX' && penv ){ - __int16 size; - __int32 code; - ptr += sizeof(__int32); // jump extension header code - - while( (DWORD)(ptr - lpMemFile) < dwFileLength ){ - code = (*((__int32 *)ptr)); // read field code - ptr += sizeof(__int32); // jump field code - size = (*((__int16 *)ptr)); // read field size - ptr += sizeof(__int16); // jump field size - - BYTE * fadr = GetInstrumentHeaderFieldPointer(penv, code, size); - if(fadr && code != 'K[..') // copy field data in instrument's header - memcpy(fadr,ptr,size); // (except for keyboard mapping) - ptr += size; // jump field - } - } - // -! NEW_FEATURE#0027 return TRUE; @@ -1827,28 +1807,8 @@ // Leave if no extra instrument settings are available (end of file reached) if(dwMemPos >= dwFileLength) return TRUE; - // Get file pointer to match the first byte of extra settings informations - ptr = (BYTE *)(lpMemFile+dwMemPos); + ReadExtendedInstrumentProperties(penv, lpMemFile + dwMemPos, dwFileLength - dwMemPos); - // Seek for supported extended settings header - if( (*((__int32 *)ptr)) == 'MPTX' && penv ){ - __int16 size; - __int32 code; - ptr += sizeof(__int32); // jump extension header code - - while( (DWORD)(ptr - lpMemFile) < dwFileLength ){ - code = (*((__int32 *)ptr)); // read field code - ptr += sizeof(__int32); // jump field code - size = (*((__int16 *)ptr)); // read field size - ptr += sizeof(__int16); // jump field size - - BYTE * fadr = GetInstrumentHeaderFieldPointer(penv, code, size); - if(fadr && code != 'K[..') // copy field data in instrument's header - memcpy(fadr,ptr,size); // (except for keyboard mapping) - ptr += size; // jump field - } - } - // -! NEW_FEATURE#0027 return TRUE; @@ -2043,6 +2003,73 @@ } + +bool IsValidSizeField(const LPCBYTE pData, const LPCBYTE pEnd, const int16 size) +//------------------------------------------------------------------------------ +{ + if(size < 0 || (uintptr_t)(pEnd - pData) < (uintptr_t)size) + return false; + else + return true; +} + + +void ReadInstrumentExtensionField(INSTRUMENTHEADER* penv, LPCBYTE& ptr, const int32 code, const int16 size) +//------------------------------------------------------------------------------------------------------------ +{ + // get field's address in instrument's header + BYTE* fadr = GetInstrumentHeaderFieldPointer(penv, code, size); + + if(fadr && code != 'K[..') // copy field data in instrument's header + memcpy(fadr,ptr,size); // (except for keyboard mapping) + ptr += size; // jump field +} + + +void ReadExtendedInstrumentProperty(INSTRUMENTHEADER* penv, const int32 code, LPCBYTE& pData, const LPCBYTE pEnd) +//--------------------------------------------------------------------------------------------------------------- +{ + if(pEnd < pData || uintptr_t(pEnd - pData) < 2) + return; + + int16 size; + memcpy(&size, pData, sizeof(size)); // read field size + pData += sizeof(size); // jump field size + + if(IsValidSizeField(pData, pEnd, size) == false) + return; + + ReadInstrumentExtensionField(penv, pData, code, size); +} + + +void ReadExtendedInstrumentProperties(INSTRUMENTHEADER* penv, const LPCBYTE pDataStart, const size_t nMemLength) +//-------------------------------------------------------------------------------------------------------------- +{ + if(penv == 0 || pDataStart == 0 || nMemLength < 4) + return; + + LPCBYTE pData = pDataStart; + const LPCBYTE pEnd = pDataStart + nMemLength; + + int32 code; + memcpy(&code, pData, sizeof(code)); + + // Seek for supported extended settings header + if( code == 'MPTX' ) + { + pData += sizeof(code); // jump extension header code + + while( (uintptr_t)(pData - pDataStart) <= nMemLength - 4) + { + memcpy(&code, pData, sizeof(code)); // read field code + pData += sizeof(code); // jump field code + ReadExtendedInstrumentProperty(penv, code, pData, pEnd); + } + } +} + + /////////////////////////////////////////////////////////////////////////////////////////////////// // 8SVX Samples Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2009-06-12 16:25:54 UTC (rev 267) +++ trunk/OpenMPT/soundlib/Sndfile.h 2009-06-12 17:32:08 UTC (rev 268) @@ -1086,8 +1086,13 @@ void WriteInstrumentPropertyForAllInstruments(__int32 code, __int16 size, FILE* f, INSTRUMENTHEADER* instruments[], UINT nInstruments); void SaveExtendedInstrumentProperties(INSTRUMENTHEADER *instruments[], UINT nInstruments, FILE* f); void SaveExtendedSongProperties(FILE* f); - void LoadExtendedSongProperties(const MODTYPE modtype, BYTE*& ptr, const BYTE* startpos, const size_t seachlimit); + void LoadExtendedSongProperties(const MODTYPE modtype, LPCBYTE ptr, const LPCBYTE startpos, const size_t seachlimit, bool* pInterpretMptMade = NULL); + // Reads extended instrument properties(XM/IT/MPTM). + // If no errors occur and song extension tag is found, returns pointer to the beginning + // of the tag, else returns NULL. + LPCBYTE LoadExtendedInstrumentProperties(const LPCBYTE pStart, const LPCBYTE pEnd, bool* pInterpretMptMade = NULL); + #endif // MODPLUG_NO_FILESAVE // MOD Convert function UINT GetBestSaveFormat() const; @@ -1515,4 +1520,18 @@ #endif +// Used in instrument/song extension reading to make sure the size field is valid. +bool IsValidSizeField(const LPCBYTE pData, const LPCBYTE pEnd, const int16 size); + +// Read instrument property with 'code' and 'size' from 'ptr' to instrument 'penv'. +// Note: (ptr, size) pair must be valid (e.g. can read 'size' bytes from 'ptr') +void ReadInstrumentExtensionField(INSTRUMENTHEADER* penv, LPCBYTE& ptr, const int32 code, const int16 size); + +// Read instrument property with 'code' from 'pData' to instrument 'penv'. +void ReadExtendedInstrumentProperty(INSTRUMENTHEADER* penv, const int32 code, LPCBYTE& pData, const LPCBYTE pEnd); + +// Read extended instrument properties from 'pDataStart' to instrument 'penv'. +void ReadExtendedInstrumentProperties(INSTRUMENTHEADER* penv, const LPCBYTE pDataStart, const size_t nMemLength); + + #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <rel...@us...> - 2009-06-14 21:49:09
|
Revision: 269 http://modplug.svn.sourceforge.net/modplug/?rev=269&view=rev Author: relabsoluness Date: 2009-06-14 21:48:05 +0000 (Sun, 14 Jun 2009) Log Message: ----------- (Patch from coda, merged somewhat modified with related refactoring) + Sample tab: Sample drawing. + Sample tab: Add silence to sample. Modified Paths: -------------- trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/Mptrack.cpp trunk/OpenMPT/mptrack/View_smp.cpp trunk/OpenMPT/mptrack/View_smp.h trunk/OpenMPT/mptrack/dlg_misc.cpp trunk/OpenMPT/mptrack/dlg_misc.h trunk/OpenMPT/mptrack/mptrack.rc trunk/OpenMPT/mptrack/res/smptoolb.bmp trunk/OpenMPT/mptrack/resource.h Added Paths: ----------- trunk/OpenMPT/soundlib/modsmp_ctrl.cpp trunk/OpenMPT/soundlib/modsmp_ctrl.h Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2009-06-12 17:32:08 UTC (rev 268) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2009-06-14 21:48:05 UTC (rev 269) @@ -7,6 +7,7 @@ #include "moddoc.h" #include "dlg_misc.h" #include "dlsbank.h" +#include "modsmp_ctrl.h" #pragma warning(disable:4244) //"conversion from 'type1' to 'type2', possible loss of data" @@ -995,84 +996,13 @@ BOOL CModDoc::AdjustEndOfSample(UINT nSample) //------------------------------------------- { - const MODINSTRUMENT *pins; + MODINSTRUMENT *pins; if (nSample >= MAX_SAMPLES) return FALSE; pins = &m_SndFile.Ins[nSample]; if ((!pins->nLength) || (!pins->pSample)) return FALSE; - BEGIN_CRITICAL(); - UINT len = pins->nLength; - if (pins->uFlags & CHN_16BIT) - { - signed short *p = (signed short *)pins->pSample; - if (pins->uFlags & CHN_STEREO) - { - p[(len+3)*2] = p[(len+2)*2] = p[(len+1)*2] = p[(len)*2] = p[(len-1)*2]; - p[(len+3)*2+1] = p[(len+2)*2+1] = p[(len+1)*2+1] = p[(len)*2+1] = p[(len-1)*2+1]; - } else - { - p[len+4] = p[len+3] = p[len+2] = p[len+1] = p[len] = p[len-1]; - } - if (((pins->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP) - && (pins->nLoopEnd == pins->nLength) - && (pins->nLoopEnd > pins->nLoopStart) && (pins->nLength > 2)) - { - p[len] = p[pins->nLoopStart]; - p[len+1] = p[pins->nLoopStart+1]; - p[len+2] = p[pins->nLoopStart+2]; - p[len+3] = p[pins->nLoopStart+3]; - p[len+4] = p[pins->nLoopStart+4]; - } - } else - { - signed char *p = (signed char *)pins->pSample; - if (pins->uFlags & CHN_STEREO) - { - p[(len+3)*2] = p[(len+2)*2] = p[(len+1)*2] = p[(len)*2] = p[(len-1)*2]; - p[(len+3)*2+1] = p[(len+2)*2+1] = p[(len+1)*2+1] = p[(len)*2+1] = p[(len-1)*2+1]; - } else - { - p[len+4] = p[len+3] = p[len+2] = p[len+1] = p[len] = p[len-1]; - } - if (((pins->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP) - && (pins->nLoopEnd == pins->nLength) - && (pins->nLoopEnd > pins->nLoopStart) && (pins->nLength > 2)) - { - p[len] = p[pins->nLoopStart]; - p[len+1] = p[pins->nLoopStart+1]; - p[len+2] = p[pins->nLoopStart+2]; - p[len+3] = p[pins->nLoopStart+3]; - p[len+4] = p[pins->nLoopStart+4]; - } - } - // Update channels with new loop values - { - for (UINT i=0; i<MAX_CHANNELS; i++) if ((m_SndFile.Chn[i].pInstrument == pins) && (m_SndFile.Chn[i].nLength)) - { - if ((pins->nLoopStart + 3 < pins->nLoopEnd) && (pins->nLoopEnd <= pins->nLength)) - { - m_SndFile.Chn[i].nLoopStart = pins->nLoopStart; - m_SndFile.Chn[i].nLoopEnd = pins->nLoopEnd; - m_SndFile.Chn[i].nLength = pins->nLoopEnd; - if (m_SndFile.Chn[i].nPos > m_SndFile.Chn[i].nLength) - { - m_SndFile.Chn[i].nPos = m_SndFile.Chn[i].nLoopStart; - m_SndFile.Chn[i].dwFlags &= ~CHN_PINGPONGFLAG; - } - DWORD d = m_SndFile.Chn[i].dwFlags & ~(CHN_PINGPONGLOOP|CHN_LOOP); - if (pins->uFlags & CHN_LOOP) - { - d |= CHN_LOOP; - if (pins->uFlags & CHN_PINGPONGLOOP) d |= CHN_PINGPONGLOOP; - } - m_SndFile.Chn[i].dwFlags = d; - } else - if (!(pins->uFlags & CHN_LOOP)) - { - m_SndFile.Chn[i].dwFlags &= ~(CHN_PINGPONGLOOP|CHN_LOOP); - } - } - } - END_CRITICAL(); + + ctrlSmp::AdjustEndOfSample(*pins, &m_SndFile); + return TRUE; } Modified: trunk/OpenMPT/mptrack/Mptrack.cpp =================================================================== --- trunk/OpenMPT/mptrack/Mptrack.cpp 2009-06-12 17:32:08 UTC (rev 268) +++ trunk/OpenMPT/mptrack/Mptrack.cpp 2009-06-14 21:48:05 UTC (rev 269) @@ -19,7 +19,7 @@ #include <shlwapi.h> // rewbs.memLeak -#define CRTDBG_MAP_ALLOC +#define _CRTDBG_MAP_ALLOC #include <stdlib.h> #include <crtdbg.h> #include ".\mptrack.h" @@ -1686,6 +1686,8 @@ "http://www.hermannseib.com/english/vsthost.htm|" "Ian Luck for UNMO3|" "http://www.un4seen.com/mo3.html|" + "coda for sample drawing code|" + "http://coda.s3m.us/|" "Pel K. Txnder for the scrolling credits control :)|" "http://tinyurl.com/4yze8|" "The people at Modplug forums for crucial contribution|" Modified: trunk/OpenMPT/mptrack/View_smp.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_smp.cpp 2009-06-12 17:32:08 UTC (rev 268) +++ trunk/OpenMPT/mptrack/View_smp.cpp 2009-06-14 21:48:05 UTC (rev 269) @@ -9,7 +9,13 @@ #include "channelManagerDlg.h" #include "view_smp.h" #include "midi.h" +#include "dlg_misc.h" +#include "modsmp_ctrl.h" +#define new DEBUG_NEW + + + // Non-client toolbar #define SMP_LEFTBAR_CY 29 #define SMP_LEFTBAR_CXSEP 14 @@ -31,6 +37,8 @@ ID_SAMPLE_ZOOMUP, ID_SAMPLE_ZOOMDOWN, ID_SEPARATOR, + ID_SAMPLE_DRAW, + ID_SAMPLE_ADDSILENCE, }; @@ -75,6 +83,8 @@ ON_COMMAND(ID_SAMPLE_SETSUSTAINEND, OnSetSustainEnd) ON_COMMAND(ID_SAMPLE_ZOOMUP, OnZoomUp) ON_COMMAND(ID_SAMPLE_ZOOMDOWN, OnZoomDown) + ON_COMMAND(ID_SAMPLE_DRAW, OnDrawingToggle) + ON_COMMAND(ID_SAMPLE_ADDSILENCE, OnAddSilence) ON_MESSAGE(WM_MOD_MIDIMSG, OnMidiMsg) ON_MESSAGE(WM_MOD_KEYCOMMAND, OnCustomKeyMsg) //rewbs.customKeys //}}AFX_MSG_MAP @@ -103,6 +113,7 @@ //--------------------------------- { m_dwBeginSel = m_dwEndSel = 0; + m_bDrawingEnabled = false; // sample drawing ModifyStyleEx(0, WS_EX_ACCEPTFILES); CModScrollView::OnInitialUpdate(); CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); @@ -179,6 +190,7 @@ pModDoc->SetFollowWnd(m_hWnd, MPTNOTIFY_SAMPLE|nSmp); if (nSmp == m_nSample) return FALSE; m_dwBeginSel = m_dwEndSel = 0; + m_bDrawingEnabled = false; // sample drawing CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); if (pMainFrm) pMainFrm->SetInfoText(""); m_nSample = nSmp; @@ -394,6 +406,13 @@ UpdateNcButtonState(); InvalidateSample(); } + + // sample drawing + if(dwHintMask & HINT_SAMPLEINFO) + { + m_bDrawingEnabled = false; + UpdateNcButtonState(); + } } #define YCVT(n, bits) (ymed - (((n) * yrange) >> (bits))) @@ -987,6 +1006,8 @@ { case ID_SAMPLE_ZOOMUP: nImage = 1; break; case ID_SAMPLE_ZOOMDOWN: nImage = 2; break; + case ID_SAMPLE_DRAW: nImage = (dwStyle & NCBTNS_DISABLED) ? 18 : 16; break; + case ID_SAMPLE_ADDSILENCE: nImage = 17; break; } pDC->Draw3dRect(rect.left-1, rect.top-1, SMP_LEFTBAR_CXBTN+2, SMP_LEFTBAR_CYBTN+2, c3, c4); pDC->Draw3dRect(rect.left, rect.top, SMP_LEFTBAR_CXBTN, SMP_LEFTBAR_CYBTN, c1, c2); @@ -1061,6 +1082,15 @@ dwStyle |= NCBTNS_MOUSEOVER; if (m_dwStatus & SMPSTATUS_NCLBTNDOWN) dwStyle |= NCBTNS_PUSHED; } + + switch(cLeftBarButtons[i]) + { + case ID_SAMPLE_DRAW: + if(m_bDrawingEnabled) dwStyle |= NCBTNS_CHECKED; + if(pSndFile->Ins[m_nSample].GetNumChannels() > 1) dwStyle |= NCBTNS_DISABLED; + break; + } + if (dwStyle != m_NcButtonState[i]) { m_NcButtonState[i] = dwStyle; @@ -1163,6 +1193,41 @@ } +template<class T, class uT> +T CViewSample::GetSampleValueFromPoint(const CPoint& point) +//------------------------------------------------------------ +{ + STATIC_ASSERT(sizeof(T) == sizeof(uT) && sizeof(T) <= 2); + int value = (std::numeric_limits<T>::max)() - (std::numeric_limits<uT>::max)() * point.y / (m_rcClient.bottom - m_rcClient.top); + Limit(value, (std::numeric_limits<T>::min)(), (std::numeric_limits<T>::max)()); + return static_cast<T>(value); +} + + +template<class T, class uT> +void CViewSample::SetInitialDrawPoint(void* pSample, const CPoint& point) +//----------------------------------------------------------------------- +{ + T* data = reinterpret_cast<T*>(pSample); + data[m_dwEndDrag] = GetSampleValueFromPoint<T, uT>(point); +} + + +template<class T, class uT> +void CViewSample::SetSampleData(void* pSample, const CPoint& point, const DWORD old ) +//----------------------------------------------------------------------------------- +{ + T* data = reinterpret_cast<T*>(pSample); + const int oldvalue = data[old]; + const int value = GetSampleValueFromPoint<T, uT>(point); + for(DWORD i=old; i != m_dwEndDrag; i += (m_dwEndDrag > old ? 1 : -1)) + { + data[i] = static_cast<T>((float)oldvalue + (value - oldvalue) * ((float)i - old) / ((float)m_dwEndDrag - old)); + } + data[m_dwEndDrag] = static_cast<T>(value); +} + + void CViewSample::OnMouseMove(UINT, CPoint point) //----------------------------------------------- { @@ -1212,7 +1277,7 @@ if (m_dwStatus & SMPSTATUS_MOUSEDRAG) { BOOL bAgain = FALSE; - DWORD len = pSndFile->Ins[m_nSample].nLength; + const DWORD len = pSndFile->Ins[m_nSample].nLength; if (!len) return; DWORD old = m_dwEndDrag; if (m_nZoom) @@ -1242,12 +1307,24 @@ point.x = m_rcClient.right; } } - LONG l = ScreenToSample(point.x); - if (l < 0) l = 0; - m_dwEndDrag = l; - if (m_dwEndDrag > len) m_dwEndDrag = len; - if (old != m_dwEndDrag) + m_dwEndDrag = ScreenToSample(point.x); + if(m_bDrawingEnabled) { + if(m_dwEndDrag < len) + { + if(pSndFile->Ins[m_nSample].GetElementarySampleSize() == 2) + SetSampleData<int16, uint16>(pSndFile->Ins[m_nSample].pSample, point, old); + else if(pSndFile->Ins[m_nSample].GetElementarySampleSize() == 1) + SetSampleData<int8, uint8>(pSndFile->Ins[m_nSample].pSample, point, old); + + ctrlSmp::AdjustEndOfSample(pSndFile->Ins[m_nSample], pSndFile); + + InvalidateSample(); + pModDoc->SetModified(); + } + } + else if (old != m_dwEndDrag) + { SetCurSel(m_dwBeginDrag, m_dwEndDrag); UpdateWindow(); } @@ -1275,6 +1352,17 @@ if (m_dwBeginDrag >= len) m_dwBeginDrag = len-1; m_dwEndDrag = m_dwBeginDrag; if (oldsel) SetCurSel(m_dwBeginDrag, m_dwEndDrag); + // set initial point for sample drawing + if (m_bDrawingEnabled) + { + if(pSndFile->Ins[m_nSample].GetElementarySampleSize() == 2) + SetInitialDrawPoint<int16, uint16>(pSndFile->Ins[m_nSample].pSample, point); + else if(pSndFile->Ins[m_nSample].GetElementarySampleSize() == 1) + SetInitialDrawPoint<int8, uint8>(pSndFile->Ins[m_nSample].pSample, point); + + InvalidateSample(); + pModDoc->SetModified(); + } } } @@ -1299,7 +1387,7 @@ { CSoundFile *pSndFile = pModDoc->GetSoundFile(); DWORD len = pSndFile->Ins[m_nSample].nLength; - if (len) SetCurSel(0, len); + if (len && !m_bDrawingEnabled) SetCurSel(0, len); } } @@ -2279,6 +2367,43 @@ } +void CViewSample::OnDrawingToggle() +//--------------------------------- +{ + m_bDrawingEnabled = !m_bDrawingEnabled; + UpdateNcButtonState(); +} + + +void CViewSample::OnAddSilence() +//------------------------------ +{ + CAddSilenceDlg dlg(this); + if (dlg.DoModal() != IDOK) return; + + CModDoc *pModDoc = GetDocument(); + if (!pModDoc) return; + CSoundFile *pSndFile = pModDoc->GetSoundFile(); + if (!pSndFile) return; + + const ctrlSmp::SmpLength nOldLength = pSndFile->Ins[m_nSample].nLength; + + if( MAX_SAMPLE_LENGTH - nOldLength < dlg.m_nSamples ) + { + CString str; str.Format(TEXT("Can't add silence because the new sample length would exceed maximum sample length %u."), MAX_SAMPLE_LENGTH); + AfxMessageBox(str, MB_ICONINFORMATION); + return; + } + + ctrlSmp::InsertSilence(pSndFile->Ins[m_nSample], dlg.m_nSamples, (dlg.m_bAddAtEnd) ? pSndFile->Ins[m_nSample].nLength : 0, pSndFile); + + if(nOldLength != pSndFile->Ins[m_nSample].nLength) + { + pModDoc->SetModified(); + pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEINFO | HINT_SAMPLEDATA, NULL); + } +} + LRESULT CViewSample::OnMidiMsg(WPARAM dwMidiDataParam, LPARAM) //------------------------------------------------------- { Modified: trunk/OpenMPT/mptrack/View_smp.h =================================================================== --- trunk/OpenMPT/mptrack/View_smp.h 2009-06-12 17:32:08 UTC (rev 268) +++ trunk/OpenMPT/mptrack/View_smp.h 2009-06-14 21:48:05 UTC (rev 269) @@ -5,7 +5,7 @@ #define SMPSTATUS_KEYDOWN 0x02 #define SMPSTATUS_NCLBTNDOWN 0x04 -#define SMP_LEFTBAR_BUTTONS 3 +#define SMP_LEFTBAR_BUTTONS 5 //====================================== class CViewSample: public CModScrollView @@ -20,6 +20,7 @@ DWORD m_dwMenuParam; DWORD m_NcButtonState[SMP_LEFTBAR_BUTTONS]; DWORD m_dwNotifyPos[MAX_CHANNELS]; + bool m_bDrawingEnabled; public: CViewSample(); @@ -42,6 +43,18 @@ BOOL GetNcButtonRect(UINT nBtn, LPRECT lpRect); void UpdateNcButtonState(); + // Sets sample data on sample draw. + template<class T, class uT> + void SetSampleData(void* pSample, const CPoint& point, const DWORD old); + + // Sets initial draw point on sample draw. + template<class T, class uT> + void SetInitialDrawPoint(void* pSample, const CPoint& point); + + // Returns sample value corresponding given point in the sample view. + template<class T, class uT> + T GetSampleValueFromPoint(const CPoint& point); + public: //{{AFX_VIRTUAL(CViewSample) virtual void OnDraw(CDC *); @@ -98,6 +111,8 @@ afx_msg void OnSetSustainEnd(); afx_msg void OnZoomUp(); afx_msg void OnZoomDown(); + afx_msg void OnDrawingToggle(); + afx_msg void OnAddSilence(); afx_msg LRESULT OnMidiMsg(WPARAM, LPARAM); afx_msg LRESULT OnCustomKeyMsg(WPARAM, LPARAM); //rewbs.customKeys //}}AFX_MSG Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp =================================================================== --- trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-06-12 17:32:08 UTC (rev 268) +++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2009-06-14 21:48:05 UTC (rev 269) @@ -1543,6 +1543,33 @@ } +// Add silence to a sample +BOOL CAddSilenceDlg::OnInitDialog() +//--------------------------------- +{ + CDialog::OnInitDialog(); + CSpinButtonCtrl *spin = (CSpinButtonCtrl *)GetDlgItem(IDC_SPIN1); + if (spin) + { + spin->SetRange(0, int16_max); + spin->SetPos(m_nSamples); + } + CButton *radio2 = (CButton *)GetDlgItem(IDC_RADIO2); + radio2->SetCheck(m_bAddAtEnd); + SetDlgItemInt(IDC_EDIT1, m_nSamples); + return TRUE; +} + + +void CAddSilenceDlg::OnOK() +//------------------------- +{ + m_nSamples = GetDlgItemInt(IDC_EDIT1); + m_bAddAtEnd = (IsDlgButtonChecked(IDC_RADIO2) != 0); + CDialog::OnOK(); +} + + //////////////////////////////////////////////////////////////////////////////// // Sound Bank Information Modified: trunk/OpenMPT/mptrack/dlg_misc.h =================================================================== --- trunk/OpenMPT/mptrack/dlg_misc.h 2009-06-12 17:32:08 UTC (rev 268) +++ trunk/OpenMPT/mptrack/dlg_misc.h 2009-06-14 21:48:05 UTC (rev 269) @@ -325,7 +325,22 @@ virtual void OnOK(); }; +//=========================== +class CAddSilenceDlg: public CDialog +//=========================== +{ +public: + UINT m_nSamples; + bool m_bAddAtEnd; +public: + CAddSilenceDlg(CWnd *parent, UINT nSamples=32):CDialog(IDD_ADDSILENCE, parent) { m_nSamples = nSamples; m_bAddAtEnd = true; } + virtual BOOL OnInitDialog(); + virtual void OnOK(); +}; + + + //////////////////////////////////////////////////////////////////////// // Sound Banks Modified: trunk/OpenMPT/mptrack/mptrack.rc =================================================================== --- trunk/OpenMPT/mptrack/mptrack.rc 2009-06-12 17:32:08 UTC (rev 268) +++ trunk/OpenMPT/mptrack/mptrack.rc 2009-06-14 21:48:05 UTC (rev 269) @@ -1929,6 +1929,26 @@ LTEXT "around current",IDC_STATIC,156,84,49,8 END +IDD_ADDSILENCE DIALOGEX 0, 0, 175, 63 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "Insert Silence" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + DEFPUSHBUTTON "OK",IDOK,118,7,50,14 + PUSHBUTTON "Cancel",IDCANCEL,118,25,50,14 + GROUPBOX "",IDC_STATIC,7,3,106,55 + EDITTEXT IDC_EDIT1,25,14,40,14,ES_AUTOHSCROLL | ES_NUMBER + CONTROL "",IDC_SPIN1,"msctls_updown32",UDS_SETBUDDYINT | + UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | + UDS_NOTHOUSANDS,57,15,11,14 + LTEXT "samples",IDC_STATIC,74,17,26,8 + CONTROL "At beginning of sample",IDC_RADIO1,"Button", + BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,11,32,89,10 + CONTROL "At end of sample",IDC_RADIO2,"Button", + BS_AUTORADIOBUTTON | WS_TABSTOP,11,46,70,10 +END + IDD_PATTERNRANDOMIZER_EFFECT DIALOGEX 0, 0, 235, 172 STYLE DS_SETFONT | DS_3DLOOK | DS_CONTROL | WS_CHILD FONT 8, "MS Sans Serif", 0, 0, 0x0 @@ -2212,6 +2232,15 @@ RIGHTMARGIN, 229 BOTTOMMARGIN, 169 END + + IDD_ADDSILENCE, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 168 + TOPMARGIN, 7 + BOTTOMMARGIN, 56 + END + END #endif // APSTUDIO_INVOKED Modified: trunk/OpenMPT/mptrack/res/smptoolb.bmp =================================================================== (Binary files differ) Modified: trunk/OpenMPT/mptrack/resource.h =================================================================== --- trunk/OpenMPT/mptrack/resource.h 2009-06-12 17:32:08 UTC (rev 268) +++ trunk/OpenMPT/mptrack/resource.h 2009-06-14 21:48:05 UTC (rev 269) @@ -105,6 +105,7 @@ #define IDS_ERR_TUNING_SERIALISATION 514 #define IDD_MIDIPARAMCONTROL 515 #define IDD_MSGBOX_HIDABLE 516 +#define IDD_ADDSILENCE 517 #define IDC_BUTTON1 1001 #define IDC_BUTTON2 1002 #define IDC_BUTTON3 1003 @@ -1056,13 +1057,15 @@ #define ID_PATTERN_DUPLICATECHANNEL 59216 #define ID_EDIT_GOTO_MENU 59220 +#define ID_SAMPLE_DRAW 59224 +#define ID_SAMPLE_ADDSILENCE 59225 // Next default values for new objects // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 517 -#define _APS_NEXT_COMMAND_VALUE 59221 +#define _APS_NEXT_RESOURCE_VALUE 518 +#define _APS_NEXT_COMMAND_VALUE 59226 #define _APS_NEXT_CONTROL_VALUE 2343 #define _APS_NEXT_SYMED_VALUE 901 #endif Added: trunk/OpenMPT/soundlib/modsmp_ctrl.cpp =================================================================== --- trunk/OpenMPT/soundlib/modsmp_ctrl.cpp (rev 0) +++ trunk/OpenMPT/soundlib/modsmp_ctrl.cpp 2009-06-14 21:48:05 UTC (rev 269) @@ -0,0 +1,152 @@ +/* + * MODINSTRUMENT related functions. + */ + +#include "stdafx.h" +#include "modsmp_ctrl.h" +#include "mptrack/MainFrm.h" + +#define new DEBUG_NEW + +namespace ctrlSmp +{ + +void ReplaceSample(MODINSTRUMENT& smp, const LPSTR pNewSample, const SmpLength nNewLength) +//---------------------------------------------------------------------------------------- +{ + LPSTR const pOldSmp = smp.pSample; + BEGIN_CRITICAL(); + smp.pSample = pNewSample; + smp.nLength = nNewLength; + END_CRITICAL(); + CSoundFile::FreeSample(pOldSmp); +} + + +SmpLength InsertSilence(MODINSTRUMENT& smp, const SmpLength nSilenceLength, const SmpLength nStartFrom, CSoundFile* pSndFile) +//---------------------------------------------------------------------------------------------------------------------------- +{ + if(nSilenceLength == 0 || nSilenceLength >= MAX_SAMPLE_LENGTH || smp.nLength > MAX_SAMPLE_LENGTH - nSilenceLength) + return smp.nLength; + + const SmpLength nOldBytes = smp.GetSampleSizeInBytes(); + const SmpLength nSilenceBytes = nSilenceLength * smp.GetElementarySampleSize() * smp.GetNumChannels(); + const SmpLength nNewSmpBytes = nOldBytes + nSilenceBytes; + const SmpLength nNewLength = smp.nLength + nSilenceLength; + + LPSTR pNewSmp = 0; + if( GetSampleCapacity(smp) >= nNewSmpBytes ) // If sample has room to expand. + { + AfxMessageBox("Not implemented: GetSampleCapacity(smp) >= nNewSmpBytes"); + // Not implemented, GetSampleCapacity() currently always returns length based value + // even if there is unused space in the sample. + } + else // Have to allocate new sample. + { + pNewSmp = CSoundFile::AllocateSample(nNewSmpBytes); + if(pNewSmp == 0) + return smp.nLength; //Sample allocation failed. + if(nStartFrom == 0) + { + memset(pNewSmp, 0, nSilenceBytes); + memcpy(pNewSmp + nSilenceBytes, smp.pSample, nOldBytes); + } + else if(nStartFrom == smp.nLength) + { + memcpy(pNewSmp, smp.pSample, nOldBytes); + memset(pNewSmp + nOldBytes, 0, nSilenceBytes); + } + else + AfxMessageBox(TEXT("Unsupported start position in InsertSilence.")); + } + + ReplaceSample(smp, pNewSmp, nNewLength); + AdjustEndOfSample(smp, pSndFile); + + return smp.nLength; +} + +namespace // Unnamed namespace for local implementation functions. +{ + +template <class T> +void AdjustEndOfSampleImpl(MODINSTRUMENT& smp) +//-------------------------------------------- +{ + MODINSTRUMENT* const pins = &smp; + const UINT len = pins->nLength; + T* p = reinterpret_cast<T*>(pins->pSample); + if (pins->uFlags & CHN_STEREO) + { + p[(len+3)*2] = p[(len+2)*2] = p[(len+1)*2] = p[(len)*2] = p[(len-1)*2]; + p[(len+3)*2+1] = p[(len+2)*2+1] = p[(len+1)*2+1] = p[(len)*2+1] = p[(len-1)*2+1]; + } else + { + p[len+4] = p[len+3] = p[len+2] = p[len+1] = p[len] = p[len-1]; + } + if (((pins->uFlags & (CHN_LOOP|CHN_PINGPONGLOOP|CHN_STEREO)) == CHN_LOOP) + && (pins->nLoopEnd == pins->nLength) + && (pins->nLoopEnd > pins->nLoopStart) && (pins->nLength > 2)) + { + p[len] = p[pins->nLoopStart]; + p[len+1] = p[pins->nLoopStart+1]; + p[len+2] = p[pins->nLoopStart+2]; + p[len+3] = p[pins->nLoopStart+3]; + p[len+4] = p[pins->nLoopStart+4]; + } +} + +} // unnamed namespace. + + +bool AdjustEndOfSample(MODINSTRUMENT& smp, CSoundFile* pSndFile) +//-------------------------------------------------------------- +{ + MODINSTRUMENT* const pins = &smp; + + if ((!pins->nLength) || (!pins->pSample)) + return false; + + BEGIN_CRITICAL(); + + if (pins->GetElementarySampleSize() == 2) + AdjustEndOfSampleImpl<int16>(*pins); + else if(pins->GetElementarySampleSize() == 1) + AdjustEndOfSampleImpl<int8>(*pins); + + // Update channels with new loop values + if(pSndFile != 0) + { + CSoundFile& rSndFile = *pSndFile; + for (UINT i=0; i<MAX_CHANNELS; i++) if ((rSndFile.Chn[i].pInstrument == pins) && (rSndFile.Chn[i].nLength)) + { + if ((pins->nLoopStart + 3 < pins->nLoopEnd) && (pins->nLoopEnd <= pins->nLength)) + { + rSndFile.Chn[i].nLoopStart = pins->nLoopStart; + rSndFile.Chn[i].nLoopEnd = pins->nLoopEnd; + rSndFile.Chn[i].nLength = pins->nLoopEnd; + if (rSndFile.Chn[i].nPos > rSndFile.Chn[i].nLength) + { + rSndFile.Chn[i].nPos = rSndFile.Chn[i].nLoopStart; + rSndFile.Chn[i].dwFlags &= ~CHN_PINGPONGFLAG; + } + DWORD d = rSndFile.Chn[i].dwFlags & ~(CHN_PINGPONGLOOP|CHN_LOOP); + if (pins->uFlags & CHN_LOOP) + { + d |= CHN_LOOP; + if (pins->uFlags & CHN_PINGPONGLOOP) d |= CHN_PINGPONGLOOP; + } + rSndFile.Chn[i].dwFlags = d; + } else + if (!(pins->uFlags & CHN_LOOP)) + { + rSndFile.Chn[i].dwFlags &= ~(CHN_PINGPONGLOOP|CHN_LOOP); + } + } + } + END_CRITICAL(); + return true; +} + + +} // namespace ctrlSmp Added: trunk/OpenMPT/soundlib/modsmp_ctrl.h =================================================================== --- trunk/OpenMPT/soundlib/modsmp_ctrl.h (rev 0) +++ trunk/OpenMPT/soundlib/modsmp_ctrl.h 2009-06-14 21:48:05 UTC (rev 269) @@ -0,0 +1,32 @@ +/* + * MODINSTRUMENT related functions. + */ + +#ifndef MODSMP_CTRL_H +#define MODSMP_CTRL_H + +#include "Sndfile.h" + +namespace ctrlSmp +{ + +typedef uintptr_t SmpLength; + +// Insert silence to given location. +// Note: Is currently implemented only for inserting silence to the beginning and to the end of the sample. +// Return: Length of the new sample. +SmpLength InsertSilence(MODINSTRUMENT& smp, const SmpLength nSilenceLength, const SmpLength nStartFrom, CSoundFile* pSndFile = 0); + +// Replaces sample in 'smp' with given sample and frees the old sample. +void ReplaceSample(MODINSTRUMENT& smp, const LPSTR pNewSample, const SmpLength nNewLength); + +bool AdjustEndOfSample(MODINSTRUMENT& smp, CSoundFile* pSndFile = 0); + +// Returns the number of bytes allocated(at least) for sample data. +// Note: Currently the return value is based on the sample length and the actual +// allocation may be more than what this function returns. +inline SmpLength GetSampleCapacity(MODINSTRUMENT& smp) {return smp.GetSampleSizeInBytes();} + +} + +#endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |