You can subscribe to this list here.
| 2006 |
Jan
|
Feb
|
Mar
(1) |
Apr
(1) |
May
|
Jun
(1) |
Jul
|
Aug
(10) |
Sep
|
Oct
|
Nov
|
Dec
(3) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2007 |
Jan
(1) |
Feb
(2) |
Mar
(3) |
Apr
(2) |
May
(10) |
Jun
(2) |
Jul
(1) |
Aug
|
Sep
|
Oct
|
Nov
(3) |
Dec
|
| 2008 |
Jan
(6) |
Feb
(4) |
Mar
(5) |
Apr
(2) |
May
(1) |
Jun
(1) |
Jul
(4) |
Aug
(6) |
Sep
(2) |
Oct
(9) |
Nov
(1) |
Dec
(4) |
| 2009 |
Jan
(9) |
Feb
(2) |
Mar
(2) |
Apr
(2) |
May
(6) |
Jun
(18) |
Jul
(33) |
Aug
(39) |
Sep
(33) |
Oct
(24) |
Nov
(23) |
Dec
(22) |
| 2010 |
Jan
(29) |
Feb
(32) |
Mar
(51) |
Apr
(17) |
May
(31) |
Jun
(21) |
Jul
(32) |
Aug
(28) |
Sep
(35) |
Oct
(27) |
Nov
(11) |
Dec
(13) |
| 2011 |
Jan
(14) |
Feb
(13) |
Mar
(27) |
Apr
(27) |
May
(28) |
Jun
(20) |
Jul
(43) |
Aug
(52) |
Sep
(66) |
Oct
(61) |
Nov
(11) |
Dec
(8) |
| 2012 |
Jan
(20) |
Feb
(30) |
Mar
(38) |
Apr
(21) |
May
(33) |
Jun
(21) |
Jul
(25) |
Aug
(9) |
Sep
(24) |
Oct
(42) |
Nov
(27) |
Dec
(41) |
| 2013 |
Jan
(20) |
Feb
(35) |
Mar
(156) |
Apr
(298) |
May
(258) |
Jun
(201) |
Jul
(105) |
Aug
(60) |
Sep
(193) |
Oct
(245) |
Nov
(280) |
Dec
(194) |
| 2014 |
Jan
(63) |
Feb
(202) |
Mar
(200) |
Apr
(23) |
May
(53) |
Jun
(105) |
Jul
(18) |
Aug
(26) |
Sep
(110) |
Oct
(187) |
Nov
(97) |
Dec
(74) |
| 2015 |
Jan
(45) |
Feb
(55) |
Mar
(116) |
Apr
(116) |
May
(193) |
Jun
(164) |
Jul
(50) |
Aug
(111) |
Sep
(98) |
Oct
(71) |
Nov
(103) |
Dec
(63) |
| 2016 |
Jan
(33) |
Feb
(101) |
Mar
(182) |
Apr
(139) |
May
(140) |
Jun
(103) |
Jul
(165) |
Aug
(286) |
Sep
(208) |
Oct
(127) |
Nov
(97) |
Dec
(54) |
| 2017 |
Jan
(64) |
Feb
(335) |
Mar
(202) |
Apr
(212) |
May
(139) |
Jun
(127) |
Jul
(294) |
Aug
(154) |
Sep
(170) |
Oct
(152) |
Nov
(156) |
Dec
(62) |
| 2018 |
Jan
(168) |
Feb
(237) |
Mar
(196) |
Apr
(174) |
May
(174) |
Jun
(161) |
Jul
(127) |
Aug
(88) |
Sep
(149) |
Oct
(66) |
Nov
(52) |
Dec
(135) |
| 2019 |
Jan
(146) |
Feb
(126) |
Mar
(104) |
Apr
(58) |
May
(60) |
Jun
(28) |
Jul
(197) |
Aug
(129) |
Sep
(141) |
Oct
(148) |
Nov
(63) |
Dec
(100) |
| 2020 |
Jan
(74) |
Feb
(37) |
Mar
(59) |
Apr
(154) |
May
(194) |
Jun
(133) |
Jul
(313) |
Aug
(197) |
Sep
(49) |
Oct
(162) |
Nov
(143) |
Dec
(57) |
| 2021 |
Jan
(120) |
Feb
(107) |
Mar
(314) |
Apr
(157) |
May
(524) |
Jun
(169) |
Jul
(72) |
Aug
(133) |
Sep
(135) |
Oct
(146) |
Nov
(198) |
Dec
(325) |
| 2022 |
Jan
(409) |
Feb
(249) |
Mar
(138) |
Apr
(95) |
May
(102) |
Jun
(221) |
Jul
(66) |
Aug
(120) |
Sep
(192) |
Oct
(131) |
Nov
(53) |
Dec
(171) |
| 2023 |
Jan
(357) |
Feb
(82) |
Mar
(168) |
Apr
(218) |
May
(196) |
Jun
(86) |
Jul
(115) |
Aug
(49) |
Sep
(190) |
Oct
(102) |
Nov
(45) |
Dec
(76) |
| 2024 |
Jan
(86) |
Feb
(50) |
Mar
(324) |
Apr
(209) |
May
(197) |
Jun
(232) |
Jul
(194) |
Aug
(247) |
Sep
(219) |
Oct
(266) |
Nov
(328) |
Dec
(304) |
| 2025 |
Jan
(191) |
Feb
(115) |
Mar
(137) |
Apr
(32) |
May
(126) |
Jun
(403) |
Jul
(213) |
Aug
(203) |
Sep
(148) |
Oct
(109) |
Nov
(191) |
Dec
(209) |
| 2026 |
Jan
(127) |
Feb
(123) |
Mar
(160) |
Apr
(141) |
May
(45) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <rel...@us...> - 2009-03-07 21:25:00
|
Revision: 251
http://modplug.svn.sourceforge.net/modplug/?rev=251&view=rev
Author: relabsoluness
Date: 2009-03-07 21:24:44 +0000 (Sat, 07 Mar 2009)
Log Message:
-----------
(Patch from Jojo, merged slightly modified)
+ Added descriptions of SBx, S3x, S4x and S5x command parameters to note properties dialog.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Moddoc.cpp
Modified: trunk/OpenMPT/mptrack/Moddoc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.cpp 2009-02-14 19:45:18 UTC (rev 250)
+++ trunk/OpenMPT/mptrack/Moddoc.cpp 2009-03-07 21:24:44 UTC (rev 251)
@@ -2420,28 +2420,28 @@
if (param)
wsprintf(s, "note+%d note+%d", param >> 4, param & 0x0F);
else
- wsprintf(s, "continue");
+ strcpy(s, "continue");
break;
case CMD_PORTAMENTOUP:
if (param)
wsprintf(s, "+%d", param);
else
- wsprintf(s, "continue");
+ strcpy(s, "continue");
break;
case CMD_PORTAMENTODOWN:
if (param)
wsprintf(s, "-%d", param);
else
- wsprintf(s, "continue");
+ strcpy(s, "continue");
break;
case CMD_TONEPORTAMENTO:
if (param)
wsprintf(s, "speed %d", param);
else
- wsprintf(s, "continue");
+ strcpy(s, "continue");
break;
case CMD_VIBRATO:
@@ -2614,7 +2614,30 @@
{
switch(param & 0xF0)
{
+ case 0x30:
+ case 0x40:
+ case 0x50:
+ if(gFXInfo[ndx].dwEffect == CMD_S3MCMDEX)
+ {
+ switch(param & 0x0F)
+ {
+ case 0x00: case 0x04: case 0x08: case 0x0C: strcpy(s, "sine wave"); break;
+ case 0x01: case 0x05: case 0x09: case 0x0D: strcpy(s, "ramp down"); break;
+ case 0x02: case 0x06: case 0x0A: case 0x0E: strcpy(s, "square wave"); break;
+ case 0x03: case 0x07: case 0x0B: case 0x0F: strcpy(s, "random"); break;
+ }
+ }
+ break;
case 0x60: if (gFXInfo[ndx].dwEffect == CMD_MODCMDEX) break;
+ case 0xB0:
+ if (gFXInfo[ndx].dwEffect == CMD_S3MCMDEX)
+ {
+ if((param & 0x0F) == 0x00)
+ strcpy(s, "loop start");
+ else
+ strcat(s, " times");
+ }
+ break;
case 0xC0:
case 0xD0: strcat(s, " frames"); break;
case 0xE0: strcat(s, " rows"); break;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2009-02-14 19:45:25
|
Revision: 250
http://modplug.svn.sourceforge.net/modplug/?rev=250&view=rev
Author: relabsoluness
Date: 2009-02-14 19:45:18 +0000 (Sat, 14 Feb 2009)
Log Message:
-----------
/ SoundTouch: Updated to SoundTouch 1.4.0
Modified Paths:
--------------
trunk/OpenMPT/soundtouch/3dnow_win.cpp
trunk/OpenMPT/soundtouch/AAFilter.cpp
trunk/OpenMPT/soundtouch/AAFilter.h
trunk/OpenMPT/soundtouch/BPMDetect.h
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.vcproj
trunk/OpenMPT/soundtouch/sse_optimized.cpp
Added Paths:
-----------
trunk/OpenMPT/soundtouch/BPMDetect.cpp
trunk/OpenMPT/soundtouch/PeakFinder.cpp
trunk/OpenMPT/soundtouch/PeakFinder.h
Removed Paths:
-------------
trunk/OpenMPT/soundtouch/soundtouch-1.3.1.zip
Modified: trunk/OpenMPT/soundtouch/3dnow_win.cpp
===================================================================
--- trunk/OpenMPT/soundtouch/3dnow_win.cpp 2009-02-14 16:22:07 UTC (rev 249)
+++ trunk/OpenMPT/soundtouch/3dnow_win.cpp 2009-02-14 19:45:18 UTC (rev 250)
@@ -24,7 +24,7 @@
/// 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
+/// http://msdn.microsoft.com/en-us/vstudio/aa718349.aspx
///
/// If the above URL is expired or removed, go to "http://msdn.microsoft.com" and
/// perform a search with keywords "processor pack".
@@ -35,10 +35,10 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2006/02/05 16:44:06 $
-// File revision : $Revision: 1.10 $
+// Last changed : $Date: 2009-01-25 16:13:39 +0200 (Sun, 25 Jan 2009) $
+// File revision : $Revision: 4 $
//
-// $Id: 3dnow_win.cpp,v 1.10 2006/02/05 16:44:06 Olli Exp $
+// $Id: 3dnow_win.cpp 51 2009-01-25 14:13:39Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
@@ -82,10 +82,10 @@
//////////////////////////////////////////////////////////////////////////////
#include "TDStretch.h"
-#include <limits.h>
+//#include <limits.h>
// these are declared in 'TDStretch.cpp'
-extern int scanOffsets[4][24];
+// extern int scanOffsets[4][24];
// Calculates cross correlation of two buffers
@@ -181,12 +181,15 @@
FIRFilter3DNow::FIRFilter3DNow() : FIRFilter()
{
filterCoeffsUnalign = NULL;
+ filterCoeffsAlign = NULL;
}
FIRFilter3DNow::~FIRFilter3DNow()
{
delete[] filterCoeffsUnalign;
+ filterCoeffsUnalign = NULL;
+ filterCoeffsAlign = NULL;
}
@@ -203,7 +206,7 @@
// 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);
+ filterCoeffsAlign = (float *)(((uint)filterCoeffsUnalign + 15) & (uint)-16);
fDivider = (float)resultDivider;
@@ -217,10 +220,10 @@
// 3DNow!-optimized version of the filter routine for stereo sound
-uint FIRFilter3DNow::evaluateFilterStereo(float *dest, const float *src, const uint numSamples) const
+uint FIRFilter3DNow::evaluateFilterStereo(float *dest, const float *src, uint numSamples) const
{
float *filterCoeffsLocal = filterCoeffsAlign;
- uint count = (numSamples - length) & -2;
+ uint count = (numSamples - length) & (uint)-2;
uint lengthLocal = length / 4;
assert(length != 0);
Modified: trunk/OpenMPT/soundtouch/AAFilter.cpp
===================================================================
--- trunk/OpenMPT/soundtouch/AAFilter.cpp 2009-02-14 16:22:07 UTC (rev 249)
+++ trunk/OpenMPT/soundtouch/AAFilter.cpp 2009-02-14 19:45:18 UTC (rev 250)
@@ -12,10 +12,10 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2006/02/05 16:44:06 $
-// File revision : $Revision: 1.9 $
+// Last changed : $Date: 2009-01-11 13:34:24 +0200 (Sun, 11 Jan 2009) $
+// File revision : $Revision: 4 $
//
-// $Id: AAFilter.cpp,v 1.9 2006/02/05 16:44:06 Olli Exp $
+// $Id: AAFilter.cpp 45 2009-01-11 11:34:24Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
@@ -58,11 +58,11 @@
*
*****************************************************************************/
-AAFilter::AAFilter(const uint length)
+AAFilter::AAFilter(uint len)
{
pFIR = FIRFilter::newInstance();
cutoffFreq = 0.5;
- setLength(length);
+ setLength(len);
}
@@ -77,7 +77,7 @@
// 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)
+void AAFilter::setCutoffFreq(double newCutoffFreq)
{
cutoffFreq = newCutoffFreq;
calculateCoeffs();
@@ -86,7 +86,7 @@
// Sets number of FIR filter taps
-void AAFilter::setLength(const uint newLength)
+void AAFilter::setLength(uint newLength)
{
length = newLength;
calculateCoeffs();
@@ -104,7 +104,7 @@
double *work;
SAMPLETYPE *coeffs;
- assert(length > 0);
+ assert(length >= 2);
assert(length % 4 == 0);
assert(cutoffFreq >= 0);
assert(cutoffFreq <= 0.5);
Modified: trunk/OpenMPT/soundtouch/AAFilter.h
===================================================================
--- trunk/OpenMPT/soundtouch/AAFilter.h 2009-02-14 16:22:07 UTC (rev 249)
+++ trunk/OpenMPT/soundtouch/AAFilter.h 2009-02-14 19:45:18 UTC (rev 250)
@@ -13,10 +13,10 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2006/02/05 16:44:06 $
-// File revision : $Revision: 1.10 $
+// Last changed : $Date: 2008-02-10 18:26:55 +0200 (Sun, 10 Feb 2008) $
+// File revision : $Revision: 4 $
//
-// $Id: AAFilter.h,v 1.10 2006/02/05 16:44:06 Olli Exp $
+// $Id: AAFilter.h 11 2008-02-10 16:26:55Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
Added: trunk/OpenMPT/soundtouch/BPMDetect.cpp
===================================================================
--- trunk/OpenMPT/soundtouch/BPMDetect.cpp (rev 0)
+++ trunk/OpenMPT/soundtouch/BPMDetect.cpp 2009-02-14 19:45:18 UTC (rev 250)
@@ -0,0 +1,311 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// 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.
+/// - Inputted 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: 2008-12-25 19:54:41 +0200 (Thu, 25 Dec 2008) $
+// File revision : $Revision: 4 $
+//
+// $Id: BPMDetect.cpp 43 2008-12-25 17:54:41Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 <math.h>
+#include <assert.h>
+#include <string.h>
+#include "FIFOSampleBuffer.h"
+#include "PeakFinder.h"
+#include "BPMDetect.h"
+
+using namespace soundtouch;
+
+#define INPUT_BLOCK_SAMPLES 2048
+#define DECIMATED_BLOCK_SAMPLES 256
+
+typedef unsigned short ushort;
+
+/// decay constant for calculating RMS volume sliding average approximation
+/// (time constant is about 10 sec)
+const float avgdecay = 0.99986f;
+
+/// Normalization coefficient for calculating RMS sliding average approximation.
+const float avgnorm = (1 - avgdecay);
+
+
+
+BPMDetect::BPMDetect(int numChannels, int sampleRate)
+{
+ xcorr = NULL;
+
+ buffer = new FIFOSampleBuffer();
+
+ decimateSum = 0;
+ decimateCount = 0;
+ decimateBy = 0;
+
+ this->sampleRate = sampleRate;
+ this->channels = numChannels;
+
+ envelopeAccu = 0;
+
+ // Initialize RMS volume accumulator to RMS level of 3000 (out of 32768) that's
+ // a typical RMS signal level value for song data. This value is then adapted
+ // to the actual level during processing.
+#ifdef INTEGER_SAMPLES
+ // integer samples
+ RMSVolumeAccu = (3000 * 3000) / avgnorm;
+#else
+ // float samples, scaled to range [-1..+1[
+ RMSVolumeAccu = (0.092f * 0.092f) / avgnorm;
+#endif
+
+ init(numChannels, sampleRate);
+}
+
+
+
+BPMDetect::~BPMDetect()
+{
+ delete[] xcorr;
+ delete buffer;
+}
+
+
+/// low-pass filter & decimate to about 500 Hz. return number of outputted samples.
+///
+/// Decimation is used to remove the unnecessary frequencies and thus to reduce
+/// the amount of data needed to be processed as calculating autocorrelation
+/// function is a very-very heavy operation.
+///
+/// Anti-alias filtering is done simply by averaging the samples. This is really a
+/// poor-man's anti-alias filtering, but it's not so critical in this kind of application
+/// (it'd also be difficult to design a high-quality filter with steep cut-off at very
+/// narrow band)
+int BPMDetect::decimate(SAMPLETYPE *dest, const SAMPLETYPE *src, int numsamples)
+{
+ int count, outcount;
+ LONG_SAMPLETYPE out;
+
+ assert(decimateBy != 0);
+ outcount = 0;
+ for (count = 0; count < numsamples; count ++)
+ {
+ decimateSum += src[count];
+
+ decimateCount ++;
+ if (decimateCount >= decimateBy)
+ {
+ // Store every Nth sample only
+ out = (LONG_SAMPLETYPE)(decimateSum / decimateBy);
+ decimateSum = 0;
+ decimateCount = 0;
+#ifdef INTEGER_SAMPLES
+ // check ranges for sure (shouldn't actually be necessary)
+ if (out > 32767)
+ {
+ out = 32767;
+ }
+ else if (out < -32768)
+ {
+ out = -32768;
+ }
+#endif // INTEGER_SAMPLES
+ dest[outcount] = (SAMPLETYPE)out;
+ outcount ++;
+ }
+ }
+ return outcount;
+}
+
+
+
+// Calculates autocorrelation function of the sample history buffer
+void BPMDetect::updateXCorr(int process_samples)
+{
+ int offs;
+ SAMPLETYPE *pBuffer;
+
+ assert(buffer->numSamples() >= (uint)(process_samples + windowLen));
+
+ pBuffer = buffer->ptrBegin();
+ for (offs = windowStart; offs < windowLen; offs ++)
+ {
+ LONG_SAMPLETYPE sum;
+ int i;
+
+ sum = 0;
+ for (i = 0; i < process_samples; i ++)
+ {
+ sum += pBuffer[i] * pBuffer[i + offs]; // scaling the sub-result shouldn't be necessary
+ }
+// xcorr[offs] *= xcorr_decay; // decay 'xcorr' here with suitable coefficients
+ // if it's desired that the system adapts automatically to
+ // various bpms, e.g. in processing continouos music stream.
+ // The 'xcorr_decay' should be a value that's smaller than but
+ // close to one, and should also depend on 'process_samples' value.
+
+ xcorr[offs] += (float)sum;
+ }
+}
+
+
+
+// Calculates envelope of the sample data
+void BPMDetect::calcEnvelope(SAMPLETYPE *samples, int numsamples)
+{
+ const float decay = 0.7f; // decay constant for smoothing the envelope
+ const float norm = (1 - decay);
+
+ int i;
+ LONG_SAMPLETYPE out;
+ float val;
+
+ for (i = 0; i < numsamples; i ++)
+ {
+ // calc average RMS volume
+ RMSVolumeAccu *= avgdecay;
+ val = (float)fabs((float)samples[i]);
+ RMSVolumeAccu += val * val;
+
+ // cut amplitudes that are below 2 times average RMS volume
+ // (we're interested in peak values, not the silent moments)
+ val -= 2 * (float)sqrt(RMSVolumeAccu * avgnorm);
+ val = (val > 0) ? val : 0;
+
+ // smooth amplitude envelope
+ envelopeAccu *= decay;
+ envelopeAccu += val;
+ out = (LONG_SAMPLETYPE)(envelopeAccu * norm);
+
+#ifdef INTEGER_SAMPLES
+ // cut peaks (shouldn't be necessary though)
+ if (out > 32767) out = 32767;
+#endif // INTEGER_SAMPLES
+ samples[i] = (SAMPLETYPE)out;
+ }
+}
+
+
+
+void BPMDetect::inputSamples(SAMPLETYPE *samples, int numSamples)
+{
+ SAMPLETYPE decimated[DECIMATED_BLOCK_SAMPLES];
+
+ // convert from stereo to mono if necessary
+ if (channels == 2)
+ {
+ int i;
+
+ for (i = 0; i < numSamples; i ++)
+ {
+ samples[i] = (samples[i * 2] + samples[i * 2 + 1]) / 2;
+ }
+ }
+
+ // decimate
+ numSamples = decimate(decimated, samples, numSamples);
+
+ // envelope new samples and add them to buffer
+ calcEnvelope(decimated, numSamples);
+ buffer->putSamples(decimated, numSamples);
+
+ // when the buffer has enought samples for processing...
+ if ((int)buffer->numSamples() > windowLen)
+ {
+ int processLength;
+
+ // how many samples are processed
+ processLength = buffer->numSamples() - windowLen;
+
+ // ... calculate autocorrelations for oldest samples...
+ updateXCorr(processLength);
+ // ... and remove them from the buffer
+ buffer->receiveSamples(processLength);
+ }
+}
+
+
+void BPMDetect::init(int numChannels, int sampleRate)
+{
+ this->sampleRate = sampleRate;
+
+ // choose decimation factor so that result is approx. 500 Hz
+ decimateBy = sampleRate / 500;
+ assert(decimateBy > 0);
+ assert(INPUT_BLOCK_SAMPLES < decimateBy * DECIMATED_BLOCK_SAMPLES);
+
+ // Calculate window length & starting item according to desired min & max bpms
+ windowLen = (60 * sampleRate) / (decimateBy * MIN_BPM);
+ windowStart = (60 * sampleRate) / (decimateBy * MAX_BPM);
+
+ assert(windowLen > windowStart);
+
+ // allocate new working objects
+ xcorr = new float[windowLen];
+ memset(xcorr, 0, windowLen * sizeof(float));
+
+ // we do processing in mono mode
+ buffer->setChannels(1);
+ buffer->clear();
+}
+
+
+
+float BPMDetect::getBpm()
+{
+ double peakPos;
+ PeakFinder peakFinder;
+
+ // find peak position
+ peakPos = peakFinder.detectPeak(xcorr, windowStart, windowLen);
+
+ assert(decimateBy != 0);
+ if (peakPos < 1e-6) return 0.0; // detection failed.
+
+ // calculate BPM
+ return (float)(60.0 * (((double)sampleRate / (double)decimateBy) / peakPos));
+}
Modified: trunk/OpenMPT/soundtouch/BPMDetect.h
===================================================================
--- trunk/OpenMPT/soundtouch/BPMDetect.h 2009-02-14 16:22:07 UTC (rev 249)
+++ trunk/OpenMPT/soundtouch/BPMDetect.h 2009-02-14 19:45:18 UTC (rev 250)
@@ -26,10 +26,10 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2006/02/05 16:44:06 $
-// File revision : $Revision: 1.5 $
+// Last changed : $Date: 2008-12-25 14:20:01 +0200 (Thu, 25 Dec 2008) $
+// File revision : $Revision: 4 $
//
-// $Id: BPMDetect.h,v 1.5 2006/02/05 16:44:06 Olli Exp $
+// $Id: BPMDetect.h 33 2008-12-25 12:20:01Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
@@ -60,8 +60,11 @@
#include "STTypes.h"
#include "FIFOSampleBuffer.h"
+namespace soundtouch
+{
+
/// Minimum allowed BPM rate. Used to restrict accepted result above a reasonable limit.
-#define MIN_BPM 45
+#define MIN_BPM 29
/// Maximum allowed BPM rate. Used to restrict accepted result below a reasonable limit.
#define MAX_BPM 230
@@ -156,4 +159,6 @@
float getBpm();
};
+}
+
#endif // _BPMDetect_H_
Modified: trunk/OpenMPT/soundtouch/FIFOSampleBuffer.cpp
===================================================================
--- trunk/OpenMPT/soundtouch/FIFOSampleBuffer.cpp 2009-02-14 16:22:07 UTC (rev 249)
+++ trunk/OpenMPT/soundtouch/FIFOSampleBuffer.cpp 2009-02-14 19:45:18 UTC (rev 250)
@@ -15,10 +15,10 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2006/02/05 16:44:06 $
-// File revision : $Revision: 1.11 $
+// Last changed : $Date: 2008-02-10 18:26:55 +0200 (Sun, 10 Feb 2008) $
+// File revision : $Revision: 4 $
//
-// $Id: FIFOSampleBuffer.cpp,v 1.11 2006/02/05 16:44:06 Olli Exp $
+// $Id: FIFOSampleBuffer.cpp 11 2008-02-10 16:26:55Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
@@ -54,14 +54,15 @@
using namespace soundtouch;
// Constructor
-FIFOSampleBuffer::FIFOSampleBuffer(uint numChannels)
+FIFOSampleBuffer::FIFOSampleBuffer(int numChannels)
{
+ assert(numChannels > 0);
sizeInBytes = 0; // reasonable initial value
- buffer = NULL; //new SAMPLETYPE[sizeInBytes / sizeof(SAMPLETYPE)];
+ buffer = NULL;
bufferUnaligned = NULL;
samplesInBuffer = 0;
bufferPos = 0;
- channels = numChannels;
+ channels = (uint)numChannels;
}
@@ -69,16 +70,19 @@
FIFOSampleBuffer::~FIFOSampleBuffer()
{
delete[] bufferUnaligned;
+ bufferUnaligned = NULL;
+ buffer = NULL;
}
// Sets number of channels, 1 = mono, 2 = stereo
-void FIFOSampleBuffer::setChannels(const uint numChannels)
+void FIFOSampleBuffer::setChannels(int numChannels)
{
uint usedBytes;
+ assert(numChannels > 0);
usedBytes = channels * samplesInBuffer;
- channels = numChannels;
+ channels = (uint)numChannels;
samplesInBuffer = usedBytes / channels;
}
@@ -88,7 +92,7 @@
// location on to the beginning of the buffer.
void FIFOSampleBuffer::rewind()
{
- if (bufferPos)
+ if (buffer && bufferPos)
{
memmove(buffer, ptrBegin(), sizeof(SAMPLETYPE) * channels * samplesInBuffer);
bufferPos = 0;
@@ -98,10 +102,10 @@
// Adds 'numSamples' pcs of samples from the 'samples' memory position to
// the sample buffer.
-void FIFOSampleBuffer::putSamples(const SAMPLETYPE *samples, uint numSamples)
+void FIFOSampleBuffer::putSamples(const SAMPLETYPE *samples, uint nSamples)
{
- memcpy(ptrEnd(numSamples), samples, sizeof(SAMPLETYPE) * numSamples * channels);
- samplesInBuffer += numSamples;
+ memcpy(ptrEnd(nSamples), samples, sizeof(SAMPLETYPE) * nSamples * channels);
+ samplesInBuffer += nSamples;
}
@@ -111,13 +115,13 @@
// 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)
+void FIFOSampleBuffer::putSamples(uint nSamples)
{
uint req;
- req = samplesInBuffer + numSamples;
+ req = samplesInBuffer + nSamples;
ensureCapacity(req);
- samplesInBuffer += numSamples;
+ samplesInBuffer += nSamples;
}
@@ -164,14 +168,14 @@
if (capacityRequirement > getCapacity())
{
// enlarge the buffer in 4kbyte steps (round up to next 4k boundary)
- sizeInBytes = (capacityRequirement * channels * sizeof(SAMPLETYPE) + 4095) & -4096;
+ sizeInBytes = (capacityRequirement * channels * sizeof(SAMPLETYPE) + 4095) & (uint)-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);
+ temp = (SAMPLETYPE *)(((ulong)tempUnaligned + 15) & (ulong)-16);
memcpy(temp, ptrBegin(), samplesInBuffer * channels * sizeof(SAMPLETYPE));
delete[] bufferUnaligned;
buffer = temp;
Modified: trunk/OpenMPT/soundtouch/FIFOSampleBuffer.h
===================================================================
--- trunk/OpenMPT/soundtouch/FIFOSampleBuffer.h 2009-02-14 16:22:07 UTC (rev 249)
+++ trunk/OpenMPT/soundtouch/FIFOSampleBuffer.h 2009-02-14 19:45:18 UTC (rev 250)
@@ -15,10 +15,10 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2006/02/05 16:44:06 $
-// File revision : $Revision: 1.9 $
+// Last changed : $Date: 2008-02-10 18:26:55 +0200 (Sun, 10 Feb 2008) $
+// File revision : $Revision: 4 $
//
-// $Id: FIFOSampleBuffer.h,v 1.9 2006/02/05 16:44:06 Olli Exp $
+// $Id: FIFOSampleBuffer.h 11 2008-02-10 16:26:55Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
@@ -85,7 +85,7 @@
void rewind();
/// Ensures that the buffer has capacity for at least this many samples.
- void ensureCapacity(const uint capacityRequirement);
+ void ensureCapacity(uint capacityRequirement);
/// Returns current capacity.
uint getCapacity() const;
@@ -93,7 +93,7 @@
public:
/// Constructor
- FIFOSampleBuffer(uint numChannels = 2 ///< Number of channels, 1=mono, 2=stereo.
+ FIFOSampleBuffer(int numChannels = 2 ///< Number of channels, 1=mono, 2=stereo.
///< Default is stereo.
);
@@ -160,7 +160,7 @@
virtual uint numSamples() const;
/// Sets number of channels, 1 = mono, 2 = stereo.
- void setChannels(uint numChannels);
+ void setChannels(int numChannels);
/// Returns nonzero if there aren't any samples available for outputting.
virtual int isEmpty() const;
Modified: trunk/OpenMPT/soundtouch/FIFOSamplePipe.h
===================================================================
--- trunk/OpenMPT/soundtouch/FIFOSamplePipe.h 2009-02-14 16:22:07 UTC (rev 249)
+++ trunk/OpenMPT/soundtouch/FIFOSamplePipe.h 2009-02-14 19:45:18 UTC (rev 250)
@@ -26,11 +26,7 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2006/02/05 16:44:06 $
-// File revision : $Revision: 1.8 $
//
-// $Id: FIFOSamplePipe.h,v 1.8 2006/02/05 16:44:06 Olli Exp $
-//
////////////////////////////////////////////////////////////////////////////////
//
// License :
@@ -81,7 +77,7 @@
/// Adds 'numSamples' pcs of samples from the 'samples' memory position to
/// the sample buffer.
virtual void putSamples(const SAMPLETYPE *samples, ///< Pointer to samples.
- uint numSamples ///< Number of samples to insert.
+ uint numSamples ///< Number of samples to insert.
) = 0;
Modified: trunk/OpenMPT/soundtouch/FIRFilter.cpp
===================================================================
--- trunk/OpenMPT/soundtouch/FIRFilter.cpp 2009-02-14 16:22:07 UTC (rev 249)
+++ trunk/OpenMPT/soundtouch/FIRFilter.cpp 2009-02-14 19:45:18 UTC (rev 250)
@@ -20,11 +20,7 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2006/02/05 16:44:06 $
-// File revision : $Revision: 1.16 $
//
-// $Id: FIRFilter.cpp,v 1.16 2006/02/05 16:44:06 Olli Exp $
-//
////////////////////////////////////////////////////////////////////////////////
//
// License :
@@ -67,6 +63,7 @@
FIRFilter::FIRFilter()
{
resultDivFactor = 0;
+ resultDivider = 0;
length = 0;
lengthDiv8 = 0;
filterCoeffs = NULL;
@@ -90,6 +87,9 @@
#endif
assert(length != 0);
+ assert(src != NULL);
+ assert(dest != NULL);
+ assert(filterCoeffs != NULL);
end = 2 * (numSamples - length);
@@ -186,8 +186,8 @@
assert(length == newLength);
resultDivFactor = uResultDivFactor;
- //OpenMPT_change--> Fix to ambiguous pow().
- //resultDivider = (SAMPLETYPE)pow(2, resultDivFactor);
+ //OpenMPT_change-->
+ //resultDivider = (SAMPLETYPE)::pow(2, resultDivFactor);
resultDivider = (1 << resultDivFactor); // == 2^resultDivFactor
//<--
@@ -215,7 +215,6 @@
assert(length > 0);
assert(lengthDiv8 * 8 == length);
if (numSamples < length) return 0;
- assert(resultDivFactor >= 0);
if (numChannels == 2)
{
return evaluateFilterStereo(dest, src, numSamples);
@@ -231,7 +230,7 @@
void * FIRFilter::operator new(size_t s)
{
// Notice! don't use "new FIRFilter" directly, use "newInstance" to create a new instance instead!
- throw std::runtime_error("Don't use 'new FIRFilter', use 'newInstance' member instead!");
+ throw std::runtime_error("Error in FIRFilter::new: Don't use 'new FIRFilter', use 'newInstance' member instead!");
return NULL;
}
Modified: trunk/OpenMPT/soundtouch/FIRFilter.h
===================================================================
--- trunk/OpenMPT/soundtouch/FIRFilter.h 2009-02-14 16:22:07 UTC (rev 249)
+++ trunk/OpenMPT/soundtouch/FIRFilter.h 2009-02-14 19:45:18 UTC (rev 250)
@@ -11,10 +11,10 @@
///
////////////////////////////////////////////////////////////////////////////////
//
-// Last changed : $Date: 2006/02/05 16:44:06 $
-// File revision : $Revision: 1.17 $
+// Last changed : $Date: 2008-02-10 18:26:55 +0200 (Sun, 10 Feb 2008) $
+// File revision : $Revision: 4 $
//
-// $Id: FIRFilter.h,v 1.17 2006/02/05 16:44:06 Olli Exp $
+// $Id: FIRFilter.h 11 2008-02-10 16:26:55Z oparviai $
//
////////////////////////////////////////////////////////////////////////////////
//
@@ -77,7 +77,7 @@
/// Operator 'new' is overloaded so that it automatically creates a suitable instance
/// depending on if we've a MMX-capable CPU available or not.
- void * operator new(size_t s);
+ static void * operator new(size_t s);
static FIRFilter *newInstance();
Added: trunk/OpenMPT/soundtouch/PeakFinder.cpp
===================================================================
--- trunk/OpenMPT/soundtouch/PeakFinder.cpp (rev 0)
+++ trunk/OpenMPT/soundtouch/PeakFinder.cpp 2009-02-14 19:45:18 UTC (rev 250)
@@ -0,0 +1,236 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// Peak detection routine.
+///
+/// The routine detects highest value on an array of values and calculates the
+/// precise peak location as a mass-center of the 'hump' around the peak value.
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2008-12-25 19:54:41 +0200 (Thu, 25 Dec 2008) $
+// File revision : $Revision: 4 $
+//
+// $Id: PeakFinder.cpp 43 2008-12-25 17:54:41Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 <math.h>
+#include <assert.h>
+
+#include "PeakFinder.h"
+
+using namespace soundtouch;
+
+#define max(x, y) (((x) > (y)) ? (x) : (y))
+
+
+PeakFinder::PeakFinder()
+{
+}
+
+
+// Finds 'ground level' of a peak hump by starting from 'peakpos' and proceeding
+// to direction defined by 'direction' until next 'hump' after minimum value will
+// begin
+int PeakFinder::findGround(const float *data, int peakpos, int direction) const
+{
+ float refvalue;
+ int lowpos;
+ int pos;
+ int climb_count;
+ float delta;
+
+ climb_count = 0;
+ refvalue = data[peakpos];
+ lowpos = peakpos;
+
+ pos = peakpos;
+
+ while ((pos > minPos) && (pos < maxPos))
+ {
+ int prevpos;
+
+ prevpos = pos;
+ pos += direction;
+
+ // calculate derivate
+ delta = data[pos] - data[prevpos];
+ if (delta <= 0)
+ {
+ // going downhill, ok
+ if (climb_count)
+ {
+ climb_count --; // decrease climb count
+ }
+
+ // check if new minimum found
+ if (data[pos] < refvalue)
+ {
+ // new minimum found
+ lowpos = pos;
+ refvalue = data[pos];
+ }
+ }
+ else
+ {
+ // going uphill, increase climbing counter
+ climb_count ++;
+ if (climb_count > 5) break; // we've been climbing too long => it's next uphill => quit
+ }
+ }
+ return lowpos;
+}
+
+
+// Find offset where the value crosses the given level, when starting from 'peakpos' and
+// proceeds to direction defined in 'direction'
+int PeakFinder::findCrossingLevel(const float *data, float level, int peakpos, int direction) const
+{
+ float peaklevel;
+ int pos;
+
+ peaklevel = data[peakpos];
+ assert(peaklevel >= level);
+ pos = peakpos;
+ while ((pos >= minPos) && (pos < maxPos))
+ {
+ if (data[pos + direction] < level) return pos; // crossing found
+ pos += direction;
+ }
+ return -1; // not found
+}
+
+
+// Calculates the center of mass location of 'data' array items between 'firstPos' and 'lastPos'
+double PeakFinder::calcMassCenter(const float *data, int firstPos, int lastPos) const
+{
+ int i;
+ float sum;
+ float wsum;
+
+ sum = 0;
+ wsum = 0;
+ for (i = firstPos; i <= lastPos; i ++)
+ {
+ sum += (float)i * data[i];
+ wsum += data[i];
+ }
+ return sum / wsum;
+}
+
+
+
+/// get exact center of peak near given position by calculating local mass of center
+double PeakFinder::getPeakCenter(const float *data, int peakpos)
+{
+ float peakLevel; // peak level
+ int crosspos1, crosspos2; // position where the peak 'hump' crosses cutting level
+ float cutLevel; // cutting value
+ float groundLevel; // ground level of the peak
+ int gp1, gp2; // bottom positions of the peak 'hump'
+
+ // find ground positions.
+ gp1 = findGround(data, peakpos, -1);
+ gp2 = findGround(data, peakpos, 1);
+
+ groundLevel = max(data[gp1], data[gp2]);
+ peakLevel = data[peakpos];
+
+ if (groundLevel < 1e-6) return 0; // ground level too small => detection failed
+ if ((peakLevel / groundLevel) < 1.3) return 0; // peak less than 30% of the ground level => no good peak detected
+
+ // calculate 70%-level of the peak
+ cutLevel = 0.70f * peakLevel + 0.30f * groundLevel;
+ // find mid-level crossings
+ crosspos1 = findCrossingLevel(data, cutLevel, peakpos, -1);
+ crosspos2 = findCrossingLevel(data, cutLevel, peakpos, 1);
+
+ if ((crosspos1 < 0) || (crosspos2 < 0)) return 0; // no crossing, no peak..
+
+ // calculate mass center of the peak surroundings
+ return calcMassCenter(data, crosspos1, crosspos2);
+}
+
+
+
+double PeakFinder::detectPeak(const float *data, int minPos, int maxPos)
+{
+
+ int i;
+ int peakpos; // position of peak level
+ double highPeak, peak;
+
+ this->minPos = minPos;
+ this->maxPos = maxPos;
+
+ // find absolute peak
+ peakpos = minPos;
+ peak = data[minPos];
+ for (i = minPos + 1; i < maxPos; i ++)
+ {
+ if (data[i] > peak)
+ {
+ peak = data[i];
+ peakpos = i;
+ }
+ }
+
+ // Calculate exact location of the highest peak mass center
+ highPeak = getPeakCenter(data, peakpos);
+ peak = highPeak;
+
+ // Now check if the highest peak were in fact harmonic of the true base beat peak
+ // - sometimes the highest peak can be Nth harmonic of the true base peak yet
+ // just a slightly higher than the true base
+ for (i = 2; i < 10; i ++)
+ {
+ double peaktmp, tmp;
+ int i1,i2;
+
+ peakpos = (int)(highPeak / (double)i + 0.5f);
+ if (peakpos < minPos) break;
+
+ // calculate mass-center of possible base peak
+ peaktmp = getPeakCenter(data, peakpos);
+
+ // now compare to highest detected peak
+ i1 = (int)(highPeak + 0.5);
+ i2 = (int)(peaktmp + 0.5);
+ tmp = 2 * (data[i2] - data[i1]) / (data[i2] + data[i1]);
+ if (fabs(tmp) < 0.1)
+ {
+ // The highest peak is harmonic of almost as high base peak,
+ // thus use the base peak instead
+ peak = peaktmp;
+ }
+ }
+
+ return peak;
+}
+
+
Added: trunk/OpenMPT/soundtouch/PeakFinder.h
===================================================================
--- trunk/OpenMPT/soundtouch/PeakFinder.h (rev 0)
+++ trunk/OpenMPT/soundtouch/PeakFinder.h 2009-02-14 19:45:18 UTC (rev 250)
@@ -0,0 +1,93 @@
+////////////////////////////////////////////////////////////////////////////////
+///
+/// The routine detects highest value on an array of values and calculates the
+/// precise peak location as a mass-center of the 'hump' around the peak value.
+///
+/// Author : Copyright (c) Olli Parviainen
+/// Author e-mail : oparviai 'at' iki.fi
+/// SoundTouch WWW: http://www.surina.net/soundtouch
+///
+////////////////////////////////////////////////////////////////////////////////
+//
+// Last changed : $Date: 2008-12-25 19:54:41 +0200 (Thu, 25 Dec 2008) $
+// File revision : $Revision: 4 $
+//
+// $Id: PeakFinder.h 43 2008-12-25 17:54:41Z oparviai $
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+// 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 _PeakFinder_H_
+#define _PeakFinder_H_
+
+namespace soundtouch
+{
+
+class PeakFinder
+{
+protected:
+ /// Min, max allowed peak positions within the data vector
+ int minPos, maxPos;
+
+ /// Calculates the mass center between given vector items.
+ double calcMassCenter(const float *data, ///< Data vector.
+ int firstPos, ///< Index of first vector item beloging to the peak.
+ int lastPos ///< Index of last vector item beloging to the peak.
+ ) const;
+
+ /// Finds the data vector index where the monotoniously decreasing signal crosses the
+ /// given level.
+ int findCrossingLevel(const float *data, ///< Data vector.
+ float level, ///< Goal crossing level.
+ int peakpos, ///< Peak position index within the data vector.
+ int direction /// Direction where to proceed from the peak: 1 = right, -1 = left.
+ ) const;
+
+ /// Finds the 'ground' level, i.e. smallest level between two neighbouring peaks, to right-
+ /// or left-hand side of the given peak position.
+ int findGround(const float *data, /// Data vector.
+ int peakpos, /// Peak position index within the data vector.
+ int direction /// Direction where to proceed from the peak: 1 = right, -1 = left.
+ ) const;
+
+ /// get exact center of peak near given position by calculating local mass of center
+ double getPeakCenter(const float *data, int peakpos);
+
+public:
+ /// Constructor.
+ PeakFinder();
+
+ /// Detect exact peak position of the data vector by finding the largest peak 'hump'
+ /// and calculating the mass-center location of the peak hump.
+ ///
+ /// \return The location of the largest base harmonic peak hump.
+ double detectPeak(const float *data, /// Data vector to be analyzed. The data vector has
+ /// to be at least 'maxPos' items long.
+ int minPos, ///< Min allowed peak location within the vector data.
+ int maxPos ///< Max allowed peak location within the vector data.
+ );
+};
+
+}
+
+#endif // _PeakFinder_H_
Modified: trunk/OpenMPT/soundtouch/README.html
===================================================================
--- trunk/OpenMPT/soundtouch/README.html 2009-02-14 16:22:07 UTC (rev 249)
+++ trunk/OpenMPT/soundtouch/README.html 2009-02-14 19:45:18 UTC (rev 250)
@@ -18,14 +18,13 @@
</head>
<body class="normal">
<hr>
-<font color=red><h4>NOTE: SoundTouch used with OpenMPT is slightly modified version.
- The file soundtouch-1.3.1.zip, and this readme excluding this
- note, are the original SoundTouch files.
+<font color=red><h4>Note: Some of the SoundTouch files included in OpenMPT repository are modified versions
+of the original SoundTouch files. This readme, excluding this note, is the original SoundTouch readme.
</h4></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>1. Introduction </h2>
<p>SoundTouch is an open-source audio
@@ -51,37 +50,27 @@
for more information.</p>
<h3>2.1. Building in Microsoft Windows</h3>
<p>Project files for Microsoft Visual C++ 6.0 and Visual C++ .NET are
-supplied with the source code package. Please notice that SoundTouch
+supplied with the source code package. </p>
+<p> Please notice that SoundTouch
library uses processor-specific optimizations for Pentium III and AMD
-processors that require a processor pack upgrade for
-the Visual Studio 6.0 to be installed in order to support these
-optimizations. The processor pack upgrade can be downloaded from
+processors. Visual Studio .NET and later versions supports the required
+instructions by default, but Visual Studio 6.0 requires a processor pack upgrade
+to be installed in order to support these optimizations. The processor pack upgrade can be downloaded from
Microsoft site at this URL:</p>
-<p><a
- href="http://msdn.microsoft.com/vstudio/downloads/tools/ppack/default.aspx">
-http://msdn.microsoft.com/vstudio/downloads/tools/ppack/default.aspx</a></p>
+<p><a href="http://msdn.microsoft.com/en-us/vstudio/aa718349.aspx">http://msdn.microsoft.com/en-us/vstudio/aa718349.aspx</a></p>
<p>If the above URL is unavailable or removed, go
to <a href="http://msdn.microsoft.com/">http://msdn.microsoft.com</a>
-and perform a search with keywords processor pack. </p>
-<p>Visual Studio .NET supports required
-instructions by default and thus doesn't require installing the
-processor pack.</p>
-<p>To build the binaries with Visual C++ 6.0
-compiler, either run "make-win.bat" script or open the
+and perform a search with keywords "processor pack". </p>
+<p>To build the binaries with Visual C++
+compiler, either run "make-win.bat" script, or open the
appropriate project files in source code directories with Visual
Studio. The final executable will appear under the "SoundTouch\bin"
directory. If using the Visual Studio IDE instead of the
make-win.bat script, directories bin and
-lib have to be created manually to the SoundTouch
+lib may need to be created manually to the SoundTouch
package root for the final executables. The make-win.bat script
creates these directories automatically.
</p>
-<p>Also other C++ compilers than Visual C++ can be
-used, but project or makefiles then have to be adapted accordingly.
-Performance optimizations are written in Visual C++ compatible
-syntax, they may or may not be compatible with other compilers. If
-using GCC (Gnu C Compiler) compiler package such as DJGPP or Cygwin,
-please see next chapter for instructions. </p>
<h3>2.2. Building in Gnu platforms</h3>
<p>The SoundTouch library can be compiled in
practically any platform supporting GNU compiler (GCC) tools.
@@ -91,7 +80,7 @@
x86 platforms only, they are automatically disabled and replaced with
standard C routines in other processor platforms.</p>
<p>To build and install the binaries, run the
-following commands in SoundTouch/ directory:</p>
+following commands in the SoundTouch/ directory:</p>
<table border="0" cellpadding="0" cellspacing="4">
<tbody>
<tr valign="top">
@@ -125,14 +114,13 @@
</tr>
</tbody>
</table>
-<p><b>NOTE:</b> At the time of release the SoundTouch package has been
+<p><b>NOTE:</b> At the release time the SoundTouch package has been
tested
to compile in GNU/Linux platform. However, in past it's happened that
new
gcc versions aren't necessarily compatible with the assembler setttings
used in the optimized routines. <b>If you have problems getting the
-SoundTouch library compiled, try the workaround of disabling the
-optimizations</b> by editing the file "include/STTypes.h" and removing
+SoundTouch library compiled, try the workaround of disabling the optimizations</b> by editing the file "include/STTypes.h" and removing
the following definition there:</p>
<blockquote>
<pre>#define ALLOW_OPTIMIZATIONS 1</pre>
@@ -146,7 +134,7 @@
<p>
In Windows environment, the sample data format is chosen
-in file "STTypes.h" by choosing one of the following
+in file "STTypes.h" by choosing one of the following
defines:</p>
<ul>
<li><span style="font-weight: bold;">#define INTEGER_SAMPLES</span>
@@ -171,7 +159,7 @@
recommended because processing the channels separately would
result in losing the phase coherency between the channels, which
consequently would ruin the stereo effect.</p>
-<p>Sample rates between 8000-48000Hz are
+<p>Sample rates between 8000-48000H are
supported.</p>
<h3>3.2. Processing latency</h3>
<p>The processing and latency constraints of
@@ -183,8 +171,8 @@
requirement
is much shorter, see section 'About algorithms'.</li>
<li>Processing CD-quality sound (16bit stereo
-sound with 44100Hz sample rate) in real-time or faster is possible
-starting from processors equivalent to Intel Pentium 133Mhz or better,
+sound with 44100H sample rate) in real-time or faster is possible
+starting from processors equivalent to Intel Pentium 133Mh or better,
if using the "quick" processing algorithm. If not using the "quick"
mode or
if floating point sample data are being used, several times more CPU
@@ -198,8 +186,7 @@
<p><em>Sample rate transposing</em> affects
both the audio stream duration and pitch. It's implemented simply
by converting the original audio sample stream to the desired
-duration by interpolating from the original audio samples. In
-SoundTouch, linear interpolation with anti-alias filtering is
+duration by interpolating from the original audio samples. In SoundTouch, linear interpolation with anti-alias filtering is
used. Theoretically a higher-order interpolation provide better
result than 1st order linear interpolation, but in audio
application linear interpolation together with anti-alias
@@ -240,10 +227,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
@@ -255,13 +242,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
@@ -269,6 +259,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
@@ -282,7 +275,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>
@@ -294,9 +287,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">
@@ -310,9 +301,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>
@@ -326,9 +314,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>
@@ -341,8 +326,6 @@
<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>
@@ -361,13 +344,11 @@
<p><strong>CPU-specific optimizations:</strong></p>
<ul>
<li>Intel MMX optimized routines are used with
-compatible CPUs when 16bit integer sample type is used. MMX
-optimizations are available both in Win32 and Gnu/x86 platforms.
+compatible CPUs when 16bit integer sample type is used. MMX optimizations are available both in Win32 and Gnu/x86 platforms.
Compatible processors are Intel PentiumMMX and later; AMD K6-2, Athlon
and later. </li>
<li>Intel SSE optimized routines are used with
-compatible CPUs when floating point sample type is used. SSE
-optimizations are currently implemented for Win32 platform only.
+compatible CPUs when floating point sample type is used. SSE optimizations are currently implemented for Win32 platform only.
Processors compatible with SSE extension are Intel processors starting
from Pentium-III, and AMD processors starting from Athlon XP. </li>
<li>AMD 3DNow! optimized routines are used with
@@ -377,41 +358,67 @@
AMD K6-2 and Athlon (classic) CPU's; better performing SSE routines are
used with AMD processor starting from Athlon XP. </li>
</ul>
+<h3>3.6 GNU compilation issues </h3>
+<h4><b>3.6.1 Required GNU tools</b> </h4>
+<p> Bash shell, GNU C++ compiler, libtool, autoconf and automake tools are required
+for compiling
+the SoundTouch library. These are usually included with the GNU/Linux distribution, but if
+not, install these packages first. For example, in Ubuntu Linux these can be acquired and
+installed with the following command:</p>
+<pre><b>sudo apt-get install <font SIZE="2">automake autoconf libtool build-essential</font></b></pre>
+<h4><b>3.6.2 Problems with configure script or build process</b> </h4>
+<p>Incompatibilities between various GNU toolchain versions may cause errors when running the "configure" script or building the source
+codes, if your GNU tool versions are not compatible with the versions used for
+preparing the SoundTouch kit. </p>
+<p>To resolve the issue, regenerate the configure scripts with your local tool
+set by running
+the "<b>./bootstrap</b>" script included in the SoundTouch source code
+kit. After that, run the <b>configure</b> script and <b>make</b> as usually.</p>
+<h4><b>3.6.3 Compiler issues with non-x86 processors</b></h4>
+<p>SoundTouch library works also on non-x86 processors.</p>
+<p>However, in case that you get compiler errors when trying to compile for non-Intel processor, edit the file
+"<b>source\SoundTouch\Makefile.am</b>" and remove the "<b>-msse2</b>"
+flag on the <b>AM_CXXFLAGS </b>line:</p>
+<pre><b>AM_CXXFLAGS=-O3 -fcheck-new -I../../include # Note: -msse2 flag removed!</b></pre>
+<p>After that, run "<b>./bootstrap</b>" script, and then run <b>configure</b>
+and <b>make</b> again.</p>
<hr>
<h2><a name="SoundStretch"></a>4. SoundStretch audio processing utility
</h2>
<p>SoundStretch audio processing utility<br>
-Copyright (c) Olli Parviainen 2002-2005</p>
+Copyright (c) Olli Parviainen 2002-2009</p>
<p>SoundStretch is a simple command-line
application that can change tempo, pitch and playback rates of
WAV sound files. This program is intended primarily to
-demonstrate how the "SoundTouch" library can be used to
+demonstrate how the "SoundTouch" library can be used to
process sound in your own program, but it can as well be used for
processing sound files.</p>
<h3>4.1. SoundStretch Usage Instructions</h3>
<p>SoundStretch Usage syntax:</p>
<blockquote>
- <pre>soundstretch infile.wav outfile.wav [switches]</pre>
+ <pre>soundstretch infilename outfilename [switches]</pre>
</blockquote>
<p>Where: </p>
<table border="0" cellpadding="2" width="100%">
<tbody>
<tr>
<td valign="top">
- <pre>"infile.wav"</pre>
+ <pre>"infilename"</pre>
</td>
- <td valign="top">is the name of the input sound
-data file (in .WAV audio file format). </td>
+ <td valign="top">Name of the input sound
+data file (in .WAV audio file format). Give "stdin" as filename to use
+ standard input pipe. </td>
</tr>
<tr>
<td valign="top">
- <pre>"outfile.wav"</pre>
+ <pre>"outfilename"</pre>
</td>
- <td valign="top">is the name of the output sound
+ <td valign="top">Name of the output sound
file where the resulting sound is saved (in .WAV audio file format).
This parameter may be omitted if you don't want to save the
output
-(e.g. when only calculating BPM rate with '-bpm' switch).</td>
+(e.g. when only calculating BPM rate with '-bpm' switch). Give "stdout"
+ as filename to use standard output pipe.</td>
</tr>
<tr>
<td valign="top">
@@ -450,11 +457,11 @@
<td valign="top">
<pre>-bpm=n</pre>
</td>
- <td valign="top">Detect the Beats-Per-Minute
-(BPM) rate of the sound and adjust the tempo to meet 'n' BPMs. If this
-switch is defined, the "-tempo=n" switch value is ignored. If "=n" is
-omitted, i.e. switch "-bpm" is used alone, the program just calculates
-and displays the BPM rate but doesn't adjust tempo according to the BPM
+ <td valign="top">Detect the Beats-Per-Minute (BPM) rate of the sound and adjust the tempo to meet 'n'
+ BPMs. When this switch is
+ applied, the "-tempo" switch is ignored. If "=n" is
+omitted, i.e. switch "-bpm" is used alone, then the BPM rate is
+ estimated and displayed, but tempo not adjusted according to the BPM
value. </td>
</tr>
<tr>
@@ -483,57 +490,69 @@
</table>
<p>Notes:</p>
<ul>
- <li>The numerical switch values can be entered
-using either integer (e.g. "-tempo=123") or decimal (e.g.
+ <li>To use standard input/output pipes for processing, give "stdin"
+ and "stdout" as input/output filenames correspondingly. The
+ standard input/output pipes will still carry the audio data in .wav audio
+ file format.</li>
+ <li>The numerical switches allow both integer (e.g. "-tempo=123") and decimal (e.g.
"-tempo=123.45") numbers.</li>
<li>The "-naa" and/or "-quick" switches can be
used to reduce CPU usage while compromising some sound quality </li>
<li>The BPM detection algorithm works by detecting
-repeating low-frequency (<250Hz) sound patterns and thus works
-mostly with most rock/pop music with bass or drum beat. The BPM
-detection doesn't work on pieces such as classical music without
-distinct, repeating bass frequency patterns. Also pieces with varying
-tempo, varying bass patterns or very complex bass patterns (jazz, hiphop) may produce odd BPM readings. <br>
- <br>
-In cases when the bass pattern drifts a bit around a nominal beat rate
-(e.g. drummer is again drunken :), the BPM algorithm may report
-incorrect harmonic one-halft to one-thirdth of the correct BPM value;
-in such case the system could for example report BPM value of 50 or 100
-instead of correct BPM value of 150. </li>
+repeating bass or drum patterns at low frequencies of <250Hz. A
+ lower-than-expected BPM figure may be reported for music with uneven or
+ complex bass patterns. </li>
</ul>
<h3>4.2. SoundStretch usage examples </h3>
<p><strong>Example 1</strong></p>
<p>The following command increases tempo of
-the sound file "originalfile.wav" by 12.5% and saves
-result to file "destinationfile.wav":</p>
+the sound file "originalfile.wav" by 12.5% and stores result to file "destinationfile.wav":</p>
<blockquote>
<pre>soundstretch originalfile.wav destinationfile.wav -tempo=12.5</pre>
</blockquote>
<p><strong>Example 2</strong></p>
<p>The following command decreases the sound
pitch (key) of the sound file "orig.wav" by two
-semitones and saves the result to file "dest.wav":</p>
+semitones and stores the result to file "dest.wav":</p>
<blockquote>
<pre>soundstretch orig.wav dest.wav -pitch=-2</pre>
</blockquote>
<p><strong>Example 3</strong></p>
<p>The following command processes the file "orig.wav" by decreasing the sound tempo by 25.3% and
-increasing the sound pitch (key) by 1.5 semitones. Result is
-saved to file "dest.wav":</p>
+increasing the sound pitch (key) by 1.5 semitones. Resulting .wav audio data is
+directed to standard output pipe:</p>
<blockquote>
- <pre>soundstretch orig.wav dest.wav -tempo=-25.3 -pitch=1.5</pre>
+ <pre>soundstretch orig.wav stdout -tempo=-25.3 -pitch=1.5</pre>
</blockquote>
<p><strong>Example 4</strong></p>
<p>The following command detects the BPM rate
of the file "orig.wav" and adjusts the tempo to match
-100 beats per minute. Result is saved to file "dest.wav":</p>
+100 beats per minute. Result is stored to file "dest.wav":</p>
<blockquote>
<pre>soundstretch orig.wav dest.wav -bpm=100</pre>
</blockquote>
+<p><strong>Example 5</strong></p>
+<p>The following command reads .wav sound data from standard input pipe and
+estimates the BPM rate:</p>
+<blockquote>
+ <pre>soundstretch stdin -bpm</pre>
+</blockquote>
<hr>
<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 settin...
[truncated message content] |
|
From: <rel...@us...> - 2009-02-14 16:22:12
|
Revision: 249
http://modplug.svn.sourceforge.net/modplug/?rev=249&view=rev
Author: relabsoluness
Date: 2009-02-14 16:22:07 +0000 (Sat, 14 Feb 2009)
Log Message:
-----------
(Patch from Jojo, merged somewhat modified)
+ Can now optionally normalize all samples instead of just one (click normalize with shift down)
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Ctrl_smp.cpp
trunk/OpenMPT/mptrack/mptrack.rc
Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-01-29 20:46:51 UTC (rev 248)
+++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2009-02-14 16:22:07 UTC (rev 249)
@@ -1032,63 +1032,88 @@
void CCtrlSamples::OnNormalize()
//------------------------------
{
+ if(!m_pModDoc || !m_pSndFile)
+ return;
+
+ //Default case: Normalize current sample
+ UINT iMinSample = m_nSample, iMaxSample = m_nSample;
+
+ //Shift -> Normalize all samples
+ if(CMainFrame::GetInputHandler()->ShiftPressed())
+ {
+ int ans = MessageBox(GetStrI18N(TEXT("This will normalize all samples independently. Continue?")), GetStrI18N(TEXT("Normalize")), MB_YESNO | MB_ICONQUESTION);
+ if(ans == IDNO) return;
+ iMinSample = 1;
+ iMaxSample = m_pSndFile->m_nSamples;
+ }
+
+
BeginWaitCursor();
- if ((m_pModDoc) && (m_pSndFile) && (m_pSndFile->Ins[m_nSample].pSample))
+ BOOL bModified = FALSE;
+
+ for(UINT iSmp = iMinSample; iSmp <= iMaxSample; iSmp++)
{
- BOOL bOk = FALSE;
- MODINSTRUMENT *pins = &m_pSndFile->Ins[m_nSample];
-
- if (pins->uFlags & CHN_16BIT)
+ if (m_pSndFile->Ins[iSmp].pSample)
{
- 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++)
+ BOOL bOk = FALSE;
+ MODINSTRUMENT *pins = &m_pSndFile->Ins[iSmp];
+
+ if (pins->uFlags & CHN_16BIT)
{
- if (p[i] > max) max = p[i];
- if (-p[i] > max) max = -p[i];
- }
- if (max < 32767)
+ 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++)
+ {
+ if (p[i] > max) max = p[i];
+ if (-p[i] > max) max = -p[i];
+ }
+ if (max < 32767)
+ {
+ max++;
+ for (UINT j=0; j<len; j++)
+ {
+ int l = p[j];
+ p[j] = (l << 15) / max;
+ }
+ bModified = bOk = TRUE;
+ }
+ } else
{
- max++;
- for (UINT j=0; j<len; j++)
+ 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++)
{
- int l = p[j];
- p[j] = (l << 15) / max;
+ if (p[i] > max) max = p[i];
+ if (-p[i] > max) max = -p[i];
}
- bOk = TRUE;
+ if (max < 127)
+ {
+ max++;
+ for (UINT j=0; j<len; j++)
+ {
+ int l = p[j];
+ p[j] = (l << 7) / max;
+ }
+ bModified = bOk = TRUE;
+ }
}
- } 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++)
+
+ if (bOk)
{
- if (p[i] > max) max = p[i];
- if (-p[i] > max) max = -p[i];
+ m_pModDoc->AdjustEndOfSample(iSmp);
+ m_pModDoc->UpdateAllViews(NULL, (iSmp << HINT_SHIFT_SMP) | HINT_SAMPLEDATA, NULL);
}
- if (max < 127)
- {
- max++;
- for (UINT j=0; j<len; j++)
- {
- int l = p[j];
- p[j] = (l << 7) / max;
- }
- bOk = TRUE;
- }
}
- if (bOk)
- {
- m_pModDoc->AdjustEndOfSample(m_nSample);
- // 05/01/05 : ericus replaced "m_nSample << 24" by "m_nSample << 20" : 4000 samples -> 12bits [see Moddoc.h]
- m_pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA, NULL);
- m_pModDoc->SetModified();
- }
}
+
+ if(bModified)
+ {
+ m_pModDoc->SetModified();
+ }
EndWaitCursor();
SwitchToView();
}
Modified: trunk/OpenMPT/mptrack/mptrack.rc
===================================================================
--- trunk/OpenMPT/mptrack/mptrack.rc 2009-01-29 20:46:51 UTC (rev 248)
+++ trunk/OpenMPT/mptrack/mptrack.rc 2009-02-14 16:22:07 UTC (rev 249)
@@ -2421,7 +2421,7 @@
IDC_SAMPLE_NEW "Create a new sample\nNew Sample"
IDC_SAMPLE_OPEN "Load sample from disk\nImport sample"
IDC_SAMPLE_SAVEAS "Save the current sample to disk\nSave sample"
- IDC_SAMPLE_NORMALIZE "Normalize the current sample (full scale)\nNormalize"
+ IDC_SAMPLE_NORMALIZE "Normalize the current sample (full scale)\nNormalize (hold shift to normalize all samples)"
IDC_SAMPLE_AMPLIFY "Amplify selection\nAmplify"
IDC_SAMPLE_UPSAMPLE "Stretch selection\nUpsample"
IDC_SAMPLE_REVERSE "Reverse selection\nReverse"
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-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-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-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-10 11:10:56
|
Revision: 244
http://modplug.svn.sourceforge.net/modplug/?rev=244&view=rev
Author: relabsoluness
Date: 2009-01-10 11:10:49 +0000 (Sat, 10 Jan 2009)
Log Message:
-----------
/ Pattern: The keyboard split 'feature' when entering chords is removed (bug 2790).
. Pattern: Undo should now work with chords.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/View_pat.cpp
trunk/OpenMPT/mptrack/pattern.h
Modified: trunk/OpenMPT/mptrack/View_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_pat.cpp 2009-01-10 07:52:25 UTC (rev 243)
+++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-01-10 11:10:49 UTC (rev 244)
@@ -4096,20 +4096,19 @@
if ((pModDoc) && (pMainFrm))
{
CSoundFile *pSndFile = pModDoc->GetSoundFile();
- MODCOMMAND *p = pSndFile->Patterns[m_nPattern], *prowbase;
- MODCOMMAND oldcmd; // This is the command we are about to overwrite
- UINT nChn = (m_dwCursor & 0xFFFF) >> 3;
+ const CHANNELINDEX nChn = GetChanFromCursor(m_dwCursor);
UINT nPlayIns = 0;
- PrepareUndo(m_dwBeginSel, m_dwEndSel);
- bool isSplit;
+ // Simply backup the whole row.
+ pModDoc->PrepareUndo(m_nPattern, nChn, m_nRow, pSndFile->GetNumChannels(), 1);
- // -- Work out where to put the new note
- prowbase = p + m_nRow * pSndFile->m_nChannels;
- p = prowbase + nChn;
- oldcmd = *p;
+ PatternRow prowbase = pSndFile->Patterns[m_nPattern].GetRow(m_nRow);
+ MODCOMMAND* p = &prowbase[nChn];
+ const MODCOMMAND oldcmd = *p; // This is the command we are about to overwrite
+
// -- establish note data
- isSplit = HandleSplit(p, note);
+ //const bool isSplit = HandleSplit(p, note);
+ HandleSplit(p, note);
PMPTCHORD pChords = pMainFrm->GetChords();
UINT baseoctave = pMainFrm->GetBaseOctave();
@@ -4117,11 +4116,12 @@
UINT nNote;
if (nchord < 3*12)
{
- UINT nchordnote;
- if (isSplit)
- nchordnote = pChords[nchord].key + baseoctave*(p->note%12) + 1;
- else
- nchordnote = pChords[nchord].key + baseoctave*12 + 1;
+ UINT nchordnote = pChords[nchord].key + baseoctave*12 + 1;
+ // Rev. 244, commented the isSplit conditions below, can't see the point in it.
+ //if (isSplit)
+ // nchordnote = pChords[nchord].key + baseoctave*(p->note%12) + 1;
+ //else
+ // nchordnote = pChords[nchord].key + baseoctave*12 + 1;
if (nchordnote <= NOTE_MAX)
{
UINT nchordch = nChn, nchno = 0;
@@ -4174,8 +4174,7 @@
InvalidateRow();
UpdateIndicator();
}
- if (((pMainFrm->GetFollowSong(pModDoc) != m_hWnd) || (pSndFile->IsPaused())
- || (!(m_dwStatus & PATSTATUS_FOLLOWSONG))))
+ if ( IsLiveRecord(*pMainFrm, *pModDoc, *pSndFile) == false )
{
if ((m_nSpacing > 0) && (m_nSpacing <= MAX_SPACING))
SetCurrentRow(m_nRow+m_nSpacing);
Modified: trunk/OpenMPT/mptrack/pattern.h
===================================================================
--- trunk/OpenMPT/mptrack/pattern.h 2009-01-10 07:52:25 UTC (rev 243)
+++ trunk/OpenMPT/mptrack/pattern.h 2009-01-10 11:10:49 UTC (rev 244)
@@ -8,7 +8,9 @@
class CPatternContainer;
+typedef MODCOMMAND* PatternRow;
+
//============
class CPattern
//============
@@ -39,6 +41,10 @@
// Return true if modcommand can be accessed from given row, false otherwise.
bool IsValidRow(const ROWINDEX iRow) const {return (iRow < GetNumRows());}
+ // Return PatternRow object which has operator[] defined so that MODCOMMAND
+ // at (iRow, iChn) can be accessed with GetRow(iRow)[iChn].
+ PatternRow GetRow(const ROWINDEX iRow) {return GetpModCommand(iRow, 0);}
+
CHANNELINDEX GetNumChannels() const;
bool Resize(const ROWINDEX newRowCount, const bool showDataLossWarning = true);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
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-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-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-03 13:36:08
|
Revision: 240
http://modplug.svn.sourceforge.net/modplug/?rev=240&view=rev
Author: relabsoluness
Date: 2009-01-03 13:36:02 +0000 (Sat, 03 Jan 2009)
Log Message:
-----------
+ Pattern: MIDI controllers can now be used to input smooth MIDI macro commands to pattern (setup->MIDI).
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Mainfrm.h
trunk/OpenMPT/mptrack/Mpdlgs.cpp
trunk/OpenMPT/mptrack/View_pat.cpp
trunk/OpenMPT/mptrack/mptrack.rc
trunk/OpenMPT/mptrack/resource.h
Modified: trunk/OpenMPT/mptrack/Mainfrm.h
===================================================================
--- trunk/OpenMPT/mptrack/Mainfrm.h 2008-12-21 13:30:05 UTC (rev 239)
+++ trunk/OpenMPT/mptrack/Mainfrm.h 2009-01-03 13:36:02 UTC (rev 240)
@@ -228,6 +228,7 @@
#define MIDISETUP_RECORDNOTEOFF 0x10
#define MIDISETUP_RESPONDTOPLAYCONTROLMSGS 0x20
#define MIDISETUP_AMPLIFYVELOCITY 0x40
+#define MIDISETUP_MIDIMACROCONTROL 0x80
Modified: trunk/OpenMPT/mptrack/Mpdlgs.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Mpdlgs.cpp 2008-12-21 13:30:05 UTC (rev 239)
+++ trunk/OpenMPT/mptrack/Mpdlgs.cpp 2009-01-03 13:36:02 UTC (rev 240)
@@ -1090,6 +1090,7 @@
ON_COMMAND(IDC_CHECK3, OnSettingsChanged)
ON_COMMAND(IDC_CHECK4, OnSettingsChanged)
ON_COMMAND(IDC_MIDI_TO_PLUGIN, OnSettingsChanged)
+ ON_COMMAND(IDC_MIDI_MACRO_CONTROL, OnSettingsChanged)
ON_COMMAND(IDC_MIDIVOL_TO_NOTEVOL, OnSettingsChanged)
ON_COMMAND(IDC_MIDIPLAYCONTROL, OnSettingsChanged)
END_MESSAGE_MAP()
@@ -1119,6 +1120,7 @@
if (m_dwMidiSetup & MIDISETUP_AMPLIFYVELOCITY) CheckDlgButton(IDC_CHECK3, MF_CHECKED);
if (m_dwMidiSetup & MIDISETUP_TRANSPOSEKEYBOARD) CheckDlgButton(IDC_CHECK4, MF_CHECKED);
if (m_dwMidiSetup & MIDISETUP_MIDITOPLUG) CheckDlgButton(IDC_MIDI_TO_PLUGIN, MF_CHECKED);
+ 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);
// Midi In Device
@@ -1154,6 +1156,7 @@
if (IsDlgButtonChecked(IDC_CHECK3)) m_dwMidiSetup |= MIDISETUP_AMPLIFYVELOCITY;
if (IsDlgButtonChecked(IDC_CHECK4)) m_dwMidiSetup |= MIDISETUP_TRANSPOSEKEYBOARD;
if (IsDlgButtonChecked(IDC_MIDI_TO_PLUGIN)) m_dwMidiSetup |= MIDISETUP_MIDITOPLUG;
+ 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;
Modified: trunk/OpenMPT/mptrack/View_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_pat.cpp 2008-12-21 13:30:05 UTC (rev 239)
+++ trunk/OpenMPT/mptrack/View_pat.cpp 2009-01-03 13:36:02 UTC (rev 240)
@@ -2953,6 +2953,21 @@
break;
}
+ // 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;
+ }
+ }
+ }
+
default:
if(CMainFrame::m_dwMidiSetup & MIDISETUP_RESPONDTOPLAYCONTROLMSGS)
{
@@ -3574,7 +3589,7 @@
CMainFrame *pMainFrm = CMainFrame::GetMainFrame();
CModDoc *pModDoc = GetDocument();
- if ((pModDoc) && (pMainFrm))
+ if ((pModDoc) && (pMainFrm) && (IsEditingEnabled_bmsg()))
{
CSoundFile *pSndFile = pModDoc->GetSoundFile();
@@ -3602,8 +3617,8 @@
p->command = (p->param <= maxspd) ? CMD_SPEED : CMD_TEMPO;
}
- if (IsEditingEnabled_bmsg())
- {
+ //if (IsEditingEnabled_bmsg())
+ //{
DWORD sel = (m_nRow << 16) | m_dwCursor;
SetCurSel(sel, sel);
sel &= ~7;
@@ -3613,8 +3628,8 @@
InvalidateArea(sel, sel+5);
UpdateIndicator();
}
- }
- } // end if mainframe & moddoc exist
+ //}
+ } // end if mainframe & moddoc exist & editing enabled
}
@@ -3624,7 +3639,7 @@
CMainFrame *pMainFrm = CMainFrame::GetMainFrame();
CModDoc *pModDoc = GetDocument();
- if ((pModDoc) && (pMainFrm))
+ if ((pModDoc) && (pMainFrm) && (IsEditingEnabled_bmsg()))
{
CSoundFile *pSndFile = pModDoc->GetSoundFile();
MODCOMMAND oldcmd; // This is the command we are about to overwrite
@@ -3660,8 +3675,8 @@
p->command = (p->param <= maxspd) ? CMD_SPEED : CMD_TEMPO;
}
- if (IsEditingEnabled())
- {
+ //if (IsEditingEnabled())
+ //{
DWORD sel = (m_nRow << 16) | m_dwCursor;
SetCurSel(sel, sel);
sel &= ~7;
@@ -3671,7 +3686,7 @@
InvalidateArea(sel, sel+5);
UpdateIndicator();
}
- }
+ //}
}
}
void CViewPattern::TempStopNote(int note, bool fromMidi)
Modified: trunk/OpenMPT/mptrack/mptrack.rc
===================================================================
--- trunk/OpenMPT/mptrack/mptrack.rc 2008-12-21 13:30:05 UTC (rev 239)
+++ trunk/OpenMPT/mptrack/mptrack.rc 2009-01-03 13:36:02 UTC (rev 240)
@@ -458,12 +458,12 @@
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,63,136,10
END
-IDD_MIDISETUP DIALOGEX 0, 0, 240, 180
+IDD_MIDISETUP DIALOGEX 0, 0, 240, 191
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,3,235,174
+ 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 |
WS_TABSTOP
@@ -472,13 +472,13 @@
COMBOBOX IDC_COMBO2,13,54,144,73,CBS_DROPDOWNLIST | NOT
WS_VISIBLE | WS_VSCROLL | WS_TABSTOP
CONTROL "Transpose external midi keyboard",IDC_CHECK4,"Button",
- BS_AUTOCHECKBOX | WS_TABSTOP,11,81,126,10
+ BS_AUTOCHECKBOX | WS_TABSTOP,11,82,126,9
CONTROL "Amplify Midi Velocity",IDC_CHECK3,"Button",
- BS_AUTOCHECKBOX | WS_TABSTOP,11,94,113,10
+ BS_AUTOCHECKBOX | WS_TABSTOP,11,93,113,9
CONTROL "Record note velocity",IDC_CHECK1,"Button",
- BS_AUTOCHECKBOX | BS_TOP | WS_TABSTOP,11,108,132,10
+ BS_AUTOCHECKBOX | BS_TOP | WS_TABSTOP,11,104,132,9
CONTROL "Record Note Off (Instruments Only)",IDC_CHECK2,"Button",
- BS_AUTOCHECKBOX | WS_TABSTOP,11,134,130,10
+ 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
@@ -492,13 +492,16 @@
11,14
CONTROL "Pass MIDI to active instrument plugin (experimental)",
IDC_MIDI_TO_PLUGIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,
- 11,148,222,8
+ 11,148,222,9
CONTROL "Combine midi volume to note velocity",
IDC_MIDIVOL_TO_NOTEVOL,"Button",BS_AUTOCHECKBOX |
- WS_TABSTOP,11,121,139,10
+ WS_TABSTOP,11,115,139,9
CONTROL "Respond to play/continue/stop song messages (untested)",
IDC_MIDIPLAYCONTROL,"Button",BS_AUTOCHECKBOX |
- WS_TABSTOP,11,161,202,9
+ WS_TABSTOP,11,172,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
END
IDD_LOADRAWSAMPLE DIALOG 0, 0, 168, 84
@@ -1990,7 +1993,7 @@
IDD_MIDISETUP, DIALOG
BEGIN
- BOTTOMMARGIN, 177
+ BOTTOMMARGIN, 188
END
IDD_CONTROL_COMMENTS, DIALOG
Modified: trunk/OpenMPT/mptrack/resource.h
===================================================================
--- trunk/OpenMPT/mptrack/resource.h 2008-12-21 13:30:05 UTC (rev 239)
+++ trunk/OpenMPT/mptrack/resource.h 2009-01-03 13:36:02 UTC (rev 240)
@@ -823,6 +823,7 @@
#define IDC_EQ_WARNING 2333
#define IDC_TEXT_STRETCHPARAMS 2337
#define IDC_EDIT_STRETCHPARAMS 2338
+#define IDC_MIDI_MACRO_CONTROL 2339
#define ID_FILE_NEWMOD 32771
#define ID_FILE_NEWXM 32772
#define ID_FILE_NEWS3M 32773
@@ -1054,7 +1055,7 @@
#define _APS_3D_CONTROLS 1
#define _APS_NEXT_RESOURCE_VALUE 516
#define _APS_NEXT_COMMAND_VALUE 59212
-#define _APS_NEXT_CONTROL_VALUE 2339
+#define _APS_NEXT_CONTROL_VALUE 2340
#define _APS_NEXT_SYMED_VALUE 901
#endif
#endif
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...> - 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-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-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-11-03 21:56:04
|
Revision: 235
http://modplug.svn.sourceforge.net/modplug/?rev=235&view=rev
Author: relabsoluness
Date: 2008-11-03 21:30:18 +0000 (Mon, 03 Nov 2008)
Log Message:
-----------
(Patch from Jojo, merged with some addition and modifications)
+ Sample tab: Signed/unsigned sample conversion.
+ Sample tab: Added button for phase invert to toolbar.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/CommandSet.cpp
trunk/OpenMPT/mptrack/CommandSet.h
trunk/OpenMPT/mptrack/Ctrl_smp.cpp
trunk/OpenMPT/mptrack/Ctrl_smp.h
trunk/OpenMPT/mptrack/View_smp.cpp
trunk/OpenMPT/mptrack/mptrack.rc
trunk/OpenMPT/mptrack/res/patterns.bmp
trunk/OpenMPT/mptrack/resource.h
Modified: trunk/OpenMPT/mptrack/CommandSet.cpp
===================================================================
--- trunk/OpenMPT/mptrack/CommandSet.cpp 2008-10-25 19:06:55 UTC (rev 234)
+++ trunk/OpenMPT/mptrack/CommandSet.cpp 2008-11-03 21:30:18 UTC (rev 235)
@@ -2289,6 +2289,16 @@
commands[kcVSTGUINextPresetJump].isDummy = false;
commands[kcVSTGUINextPresetJump].Message = "Plugin preset forward jump";
+ commands[kcSampleInvert].UID = 1784;
+ commands[kcSampleInvert].Message = "Invert sample phase";
+ commands[kcSampleInvert].isHidden = false;
+ commands[kcSampleInvert].isDummy = false;
+
+ commands[kcSampleSignUnsign].UID = 1785;
+ commands[kcSampleSignUnsign].Message = "Signed/Unsigned conversion";
+ commands[kcSampleSignUnsign].isHidden = false;
+ commands[kcSampleSignUnsign].isDummy = false;
+
#ifdef _DEBUG
for (int i=0; i<kcNumCommands; i++) {
if (commands[i].UID != 0) { // ignore unset UIDs
Modified: trunk/OpenMPT/mptrack/CommandSet.h
===================================================================
--- trunk/OpenMPT/mptrack/CommandSet.h 2008-10-25 19:06:55 UTC (rev 234)
+++ trunk/OpenMPT/mptrack/CommandSet.h 2008-11-03 21:30:18 UTC (rev 235)
@@ -566,7 +566,9 @@
kcSampleDelete,
kcSampleZoomUp,
kcSampleZoomDown,
- kcEndSampleEditing=kcSampleZoomDown,
+ kcSampleInvert,
+ kcSampleSignUnsign,
+ kcEndSampleEditing=kcSampleSignUnsign,
//kcSampStartNotes to kcInsNoteMapEndNoteStops must be contiguous.
kcSampStartNotes,
Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2008-10-25 19:06:55 UTC (rev 234)
+++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2008-11-03 21:30:18 UTC (rev 235)
@@ -65,6 +65,8 @@
ON_COMMAND(IDC_SAMPLE_DOWNSAMPLE, OnDownsample)
ON_COMMAND(IDC_SAMPLE_REVERSE, OnReverse)
ON_COMMAND(IDC_SAMPLE_SILENCE, OnSilence)
+ ON_COMMAND(IDC_SAMPLE_INVERT, OnInvert)
+ ON_COMMAND(IDC_SAMPLE_SIGN_UNSIGN, OnSignUnSign)
ON_COMMAND(IDC_CHECK1, OnSetPanningChanged)
ON_COMMAND(ID_PREVINSTRUMENT, OnPrevInstrument)
ON_COMMAND(ID_NEXTINSTRUMENT, OnNextInstrument)
@@ -209,6 +211,8 @@
m_ToolBar2.AddButton(IDC_SAMPLE_DOWNSAMPLE, 29);
m_ToolBar2.AddButton(IDC_SAMPLE_REVERSE, 11);
m_ToolBar2.AddButton(IDC_SAMPLE_SILENCE, 22);
+ m_ToolBar2.AddButton(IDC_SAMPLE_INVERT, 35);
+ m_ToolBar2.AddButton(IDC_SAMPLE_SIGN_UNSIGN, 36);
// Setup Controls
m_EditName.SetLimitText(32);
m_EditFileName.SetLimitText(22);
@@ -457,6 +461,14 @@
OnSilence();
break;
+ case IDC_SAMPLE_INVERT:
+ OnInvert();
+ break;
+
+ case IDC_SAMPLE_SIGN_UNSIGN:
+ OnSignUnSign();
+ break;
+
case IDC_SAMPLE_NORMALIZE:
OnNormalize();
break;
@@ -1075,20 +1087,17 @@
}
-void CCtrlSamples::OnAmplify()
-//----------------------------
+void CCtrlSamples::ApplyAmplify(LONG lAmp, bool bFadeIn, bool bFadeOut)
+//-----------------------------------------------------------------------
{
- static int16 snOldAmp = 100;
SAMPLEVIEWSTATE viewstate;
DWORD dwStart, dwEnd;
MODINSTRUMENT *pins;
- CAmpDlg dlg(this, snOldAmp);
memset(&viewstate, 0, sizeof(viewstate));
SendViewMessage(VIEWMSG_SAVESTATE, (LPARAM)&viewstate);
if ((!m_pModDoc) || (!m_pSndFile) || (!m_pSndFile->Ins[m_nSample].pSample)) return;
- if (dlg.DoModal() != IDOK) return;
- snOldAmp = dlg.m_nFactor;
+
BeginWaitCursor();
pins = &m_pSndFile->Ins[m_nSample];
dwStart = viewstate.dwBeginSel;
@@ -1102,8 +1111,7 @@
}
if (pins->uFlags & CHN_STEREO) { dwStart *= 2; dwEnd *= 2; }
UINT len = dwEnd - dwStart;
- LONG lAmp = dlg.m_nFactor;
- if ((dlg.m_bFadeIn) && (dlg.m_bFadeOut)) lAmp *= 4;
+ if ((bFadeIn) && (bFadeOut)) lAmp *= 4;
if (pins->uFlags & CHN_16BIT)
{
signed short *p = ((signed short *)pins->pSample) + dwStart;
@@ -1111,8 +1119,8 @@
for (UINT i=0; i<len; i++)
{
LONG l = (p[i] * lAmp) / 100;
- if (dlg.m_bFadeIn) l = (LONG)((l * (LONGLONG)i) / len);
- if (dlg.m_bFadeOut) l = (LONG)((l * (LONGLONG)(len-i)) / len);
+ if (bFadeIn) l = (LONG)((l * (LONGLONG)i) / len);
+ if (bFadeOut) l = (LONG)((l * (LONGLONG)(len-i)) / len);
if (l < -32768) l = -32768;
if (l > 32767) l = 32767;
p[i] = (signed short)l;
@@ -1124,8 +1132,8 @@
for (UINT i=0; i<len; i++)
{
LONG l = (p[i] * lAmp) / 100;
- if (dlg.m_bFadeIn) l = (LONG)((l * (LONGLONG)i) / len);
- if (dlg.m_bFadeOut) l = (LONG)((l * (LONGLONG)(len-i)) / len);
+ if (bFadeIn) l = (LONG)((l * (LONGLONG)i) / len);
+ if (bFadeOut) l = (LONG)((l * (LONGLONG)(len-i)) / len);
if (l < -128) l = -128;
if (l > 127) l = 127;
p[i] = (signed char)l;
@@ -1140,6 +1148,17 @@
}
+void CCtrlSamples::OnAmplify()
+//----------------------------
+{
+ static int16 snOldAmp = 100;
+ CAmpDlg dlg(this, snOldAmp);
+ if (dlg.DoModal() != IDOK) return;
+ snOldAmp = dlg.m_nFactor;
+ ApplyAmplify(dlg.m_nFactor, dlg.m_bFadeIn, dlg.m_bFadeOut);
+}
+
+
const int gSinc2x16Odd[16] =
{ // Kaiser window, beta=7.400
-19, 97, -295, 710, -1494, 2958, -6155, 20582, 20582, -6155, 2958, -1494, 710, -295, 97, -19,
@@ -2138,6 +2157,54 @@
}
+void CCtrlSamples::OnInvert()
+//--------------------------------
+{
+ ApplyAmplify(-100);
+}
+
+
+void CCtrlSamples::OnSignUnSign()
+//-------------------------------
+{
+ // purpose: sign/unsign a sample ("distortion")
+ SAMPLEVIEWSTATE viewstate;
+ DWORD dwStart, dwEnd;
+ MODINSTRUMENT *pins;
+
+ memset(&viewstate, 0, sizeof(viewstate));
+ SendViewMessage(VIEWMSG_SAVESTATE, (LPARAM)&viewstate);
+ if ((!m_pModDoc) || (!m_pSndFile) || (!m_pSndFile->Ins[m_nSample].pSample)) return;
+ BeginWaitCursor();
+ pins = &m_pSndFile->Ins[m_nSample];
+ dwStart = viewstate.dwBeginSel;
+ dwEnd = viewstate.dwEndSel;
+ if (dwEnd > pins->nLength) dwEnd = pins->nLength;
+ if (dwStart > dwEnd) dwStart = dwEnd;
+ if (dwStart >= dwEnd)
+ {
+ dwStart = 0;
+ dwEnd = pins->nLength;
+ }
+ if (pins->uFlags & CHN_STEREO) { dwStart *= 2; dwEnd *= 2; }
+ UINT len = dwEnd - dwStart;
+ if (pins->uFlags & CHN_16BIT)
+ {
+ signed short *p = ((signed short *)pins->pSample) + dwStart;
+ for (UINT i=0; i<len; ++i) p[i] += 0x8000; //unsign
+ } else {
+ signed char *p = ((signed char *)pins->pSample) + dwStart;
+ for (UINT i=0; i<len; ++i) p[i] += 0x80; //unsign
+ }
+
+ m_pModDoc->AdjustEndOfSample(m_nSample);
+ m_pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA, NULL);
+ m_pModDoc->SetModified();
+ EndWaitCursor();
+ SwitchToView();
+}
+
+
void CCtrlSamples::OnSilence()
//----------------------------
{
Modified: trunk/OpenMPT/mptrack/Ctrl_smp.h
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_smp.h 2008-10-25 19:06:55 UTC (rev 234)
+++ trunk/OpenMPT/mptrack/Ctrl_smp.h 2008-11-03 21:30:18 UTC (rev 235)
@@ -34,6 +34,10 @@
void UpdateTimeStretchParameterString();
void ReadTimeStretchParameters();
+ // Applies amplification to sample. Negative values
+ // can be used to invert phase.
+ void ApplyAmplify(LONG nAmp, bool bFadeIn = false, bool bFadeOut = false);
+
public:
CCtrlSamples();
~CCtrlSamples();
@@ -72,6 +76,8 @@
afx_msg void OnDownsample();
afx_msg void OnReverse();
afx_msg void OnSilence();
+ afx_msg void OnInvert();
+ afx_msg void OnSignUnSign();
afx_msg void OnNameChanged();
afx_msg void OnFileNameChanged();
afx_msg void OnVolumeChanged();
Modified: trunk/OpenMPT/mptrack/View_smp.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_smp.cpp 2008-10-25 19:06:55 UTC (rev 234)
+++ trunk/OpenMPT/mptrack/View_smp.cpp 2008-11-03 21:30:18 UTC (rev 235)
@@ -2380,10 +2380,12 @@
case kcSampleSave: PostCtrlMessage(IDC_SAMPLE_SAVEAS); return wParam;
case kcSampleNew: PostCtrlMessage(IDC_SAMPLE_NEW); return wParam;
- case kcSampleReverse: PostCtrlMessage(IDC_SAMPLE_REVERSE); return wParam;
- case kcSampleSilence: PostCtrlMessage(IDC_SAMPLE_SILENCE); return wParam;
- case kcSampleNormalize: PostCtrlMessage(IDC_SAMPLE_NORMALIZE); return wParam;
- case kcSampleAmplify: PostCtrlMessage(IDC_SAMPLE_AMPLIFY); return wParam;
+ case kcSampleReverse: PostCtrlMessage(IDC_SAMPLE_REVERSE); return wParam;
+ case kcSampleSilence: PostCtrlMessage(IDC_SAMPLE_SILENCE); return wParam;
+ case kcSampleNormalize: PostCtrlMessage(IDC_SAMPLE_NORMALIZE); return wParam;
+ case kcSampleAmplify: PostCtrlMessage(IDC_SAMPLE_AMPLIFY); return wParam;
+ case kcSampleInvert: PostCtrlMessage(IDC_SAMPLE_INVERT); return wParam;
+ case kcSampleSignUnsign: PostCtrlMessage(IDC_SAMPLE_SIGN_UNSIGN); return wParam;
case kcNoteOff: PlayNote(NOTE_KEYOFF); return wParam;
case kcNoteCut: PlayNote(NOTE_NOTECUT); return wParam;
Modified: trunk/OpenMPT/mptrack/mptrack.rc
===================================================================
--- trunk/OpenMPT/mptrack/mptrack.rc 2008-10-25 19:06:55 UTC (rev 234)
+++ trunk/OpenMPT/mptrack/mptrack.rc 2008-11-03 21:30:18 UTC (rev 235)
@@ -751,7 +751,7 @@
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
+ 0x4d,268,4,164,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
@@ -2433,6 +2433,8 @@
STRINGTABLE
BEGIN
IDC_SAMPLE_SILENCE "Silence Sample\nSilence"
+ IDC_SAMPLE_INVERT "Invert phase\nInvert phase"
+ IDC_SAMPLE_SIGN_UNSIGN "Signed/Unsigned conversion\nSigned/Unsigned conversion"
IDC_INSTRUMENT_NEW "Create a new instrument\nNew instrument (hold shift to duplicate)"
IDC_INSTRUMENT_OPEN "Import instrument\nImport instrument"
IDC_INSTRUMENT_SAVEAS "Save the current instrument to disk\nSave instrument"
Modified: trunk/OpenMPT/mptrack/res/patterns.bmp
===================================================================
(Binary files differ)
Modified: trunk/OpenMPT/mptrack/resource.h
===================================================================
--- trunk/OpenMPT/mptrack/resource.h 2008-10-25 19:06:55 UTC (rev 234)
+++ trunk/OpenMPT/mptrack/resource.h 2008-11-03 21:30:18 UTC (rev 235)
@@ -587,6 +587,8 @@
#define IDC_CHECK_EQ 2052
#define IDC_CHECK_AGC 2053
#define IDC_SAMPLE_SILENCE 2054
+#define IDC_SAMPLE_INVERT 2055
+#define IDC_SAMPLE_SIGN_UNSIGN 2056
#define IDC_INSTRUMENT_NEW 2060
#define IDC_INSTRUMENT_OPEN 2061
#define IDC_INSTRUMENT_SAVEAS 2062
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2008-10-25 19:07:02
|
Revision: 234
http://modplug.svn.sourceforge.net/modplug/?rev=234&view=rev
Author: relabsoluness
Date: 2008-10-25 19:06:55 +0000 (Sat, 25 Oct 2008)
Log Message:
-----------
+ Sample amplify now accepts negative values(inverts sample phase) (request 2219)
. Fixed a typo in Setup->Colors
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Ctrl_smp.cpp
trunk/OpenMPT/mptrack/View_pat.cpp
trunk/OpenMPT/mptrack/dlg_misc.cpp
trunk/OpenMPT/mptrack/dlg_misc.h
trunk/OpenMPT/mptrack/mptrack.rc
Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2008-10-24 18:33:16 UTC (rev 233)
+++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2008-10-25 19:06:55 UTC (rev 234)
@@ -1078,7 +1078,7 @@
void CCtrlSamples::OnAmplify()
//----------------------------
{
- static UINT snOldAmp = 100;
+ static int16 snOldAmp = 100;
SAMPLEVIEWSTATE viewstate;
DWORD dwStart, dwEnd;
MODINSTRUMENT *pins;
Modified: trunk/OpenMPT/mptrack/View_pat.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_pat.cpp 2008-10-24 18:33:16 UTC (rev 233)
+++ trunk/OpenMPT/mptrack/View_pat.cpp 2008-10-25 19:06:55 UTC (rev 234)
@@ -2595,7 +2595,7 @@
//-----------------------------------
{
static UINT snOldAmp = 100;
- CAmpDlg dlg(this, snOldAmp);
+ CAmpDlg dlg(this, snOldAmp, 0);
CModDoc *pModDoc = GetDocument();
BYTE chvol[MAX_BASECHANNELS];
@@ -2604,7 +2604,7 @@
CSoundFile *pSndFile = pModDoc->GetSoundFile();
BeginWaitCursor();
PrepareUndo(m_dwBeginSel, m_dwEndSel);
- snOldAmp = dlg.m_nFactor;
+ snOldAmp = static_cast<UINT>(dlg.m_nFactor);
memset(chvol, 64, sizeof(chvol));
if (pSndFile->Patterns[m_nPattern])
{
Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/dlg_misc.cpp 2008-10-24 18:33:16 UTC (rev 233)
+++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2008-10-25 19:06:55 UTC (rev 234)
@@ -11,7 +11,7 @@
#include "midi.h"
#include "version.h"
-#pragma warning(disable:4244)
+#pragma warning(disable:4244) //"conversion from 'type1' to 'type2', possible loss of data"
@@ -1504,6 +1504,13 @@
///////////////////////////////////////////////////////////////////////////////
// Samples
+CAmpDlg::CAmpDlg(CWnd *parent, int16 nFactor, int16 nFactorMin, int16 nFactorMax)
+//-------------------------------------------------------------------------------
+ : CDialog(IDD_SAMPLE_AMPLIFY, parent), m_nFactor(nFactor),
+ m_nFactorMin(nFactorMin), m_nFactorMax(nFactorMax),
+ m_bFadeIn(FALSE), m_bFadeOut(FALSE)
+{}
+
BOOL CAmpDlg::OnInitDialog()
//--------------------------
{
@@ -1511,8 +1518,8 @@
CSpinButtonCtrl *spin = (CSpinButtonCtrl *)GetDlgItem(IDC_SPIN1);
if (spin)
{
- spin->SetRange(10, 800);
- spin->SetPos(m_nFactor);
+ spin->SetRange32(m_nFactorMin, m_nFactorMax);
+ spin->SetPos32(m_nFactor);
}
SetDlgItemInt(IDC_EDIT1, m_nFactor);
return TRUE;
@@ -1522,9 +1529,16 @@
void CAmpDlg::OnOK()
//------------------
{
- m_nFactor = GetDlgItemInt(IDC_EDIT1);
- m_bFadeIn = IsDlgButtonChecked(IDC_CHECK1);
- m_bFadeOut = IsDlgButtonChecked(IDC_CHECK2);
+ const int nVal = static_cast<int>(GetDlgItemInt(IDC_EDIT1));
+ if(nVal < m_nFactorMin || nVal > m_nFactorMax)
+ {
+ CString str; str.Format(GetStrI18N(__TEXT("Value should be within [%d, %d]")), m_nFactorMin, m_nFactorMax);
+ AfxMessageBox(str, MB_ICONINFORMATION);
+ return;
+ }
+ m_nFactor = static_cast<int16>(nVal);
+ m_bFadeIn = (IsDlgButtonChecked(IDC_CHECK1) != 0);
+ m_bFadeOut = (IsDlgButtonChecked(IDC_CHECK2) != 0);
CDialog::OnOK();
}
Modified: trunk/OpenMPT/mptrack/dlg_misc.h
===================================================================
--- trunk/OpenMPT/mptrack/dlg_misc.h 2008-10-24 18:33:16 UTC (rev 233)
+++ trunk/OpenMPT/mptrack/dlg_misc.h 2008-10-25 19:06:55 UTC (rev 234)
@@ -316,11 +316,11 @@
//===========================
{
public:
- UINT m_nFactor;
- BOOL m_bFadeIn, m_bFadeOut;
+ int16 m_nFactor, m_nFactorMin, m_nFactorMax;
+ bool m_bFadeIn, m_bFadeOut;
public:
- CAmpDlg(CWnd *parent, UINT nFactor=100):CDialog(IDD_SAMPLE_AMPLIFY, parent) { m_nFactor = nFactor; m_bFadeIn = m_bFadeOut = FALSE; }
+ CAmpDlg(CWnd *parent, int16 nFactor=100, int16 nFactorMin = int16_min, int16 nFactorMax = int16_max);
virtual BOOL OnInitDialog();
virtual void OnOK();
};
Modified: trunk/OpenMPT/mptrack/mptrack.rc
===================================================================
--- trunk/OpenMPT/mptrack/mptrack.rc 2008-10-24 18:33:16 UTC (rev 233)
+++ trunk/OpenMPT/mptrack/mptrack.rc 2008-10-25 19:06:55 UTC (rev 234)
@@ -454,7 +454,7 @@
LTEXT "rows",IDC_STATIC,124,88,16,8
CONTROL "",IDC_BUTTON4,"Button",BS_OWNERDRAW | BS_FLAT,54,113,
114,43
- CONTROL "Set highlights to songs' time sigatures",IDC_CHECK5,
+ CONTROL "Set highlights to songs' time signatures",IDC_CHECK5,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,63,136,10
END
@@ -1310,7 +1310,7 @@
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
LTEXT "Amplify by",IDC_STATIC,13,19,37,8
- EDITTEXT IDC_EDIT1,54,16,40,14,ES_AUTOHSCROLL | ES_NUMBER
+ EDITTEXT IDC_EDIT1,54,16,40,14,ES_AUTOHSCROLL
CONTROL "Spin1",IDC_SPIN1,"msctls_updown32",UDS_SETBUDDYINT |
UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS |
UDS_NOTHOUSANDS,89,17,11,14
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-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-18 12:35:59
|
Revision: 231
http://modplug.svn.sourceforge.net/modplug/?rev=231&view=rev
Author: relabsoluness
Date: 2008-10-18 12:35:46 +0000 (Sat, 18 Oct 2008)
Log Message:
-----------
Patches from Jojo (with small modifications)
. File name in treeview wasn't updated when saving with new file name (bug 1731)
. BPM approximation showed wrong rows per beat in some cases (bug 2532)
. Playing sample selection didn't work properly in all cases (bug 1700).
. Setting loop points could affect playing of sample even if loop was disabled (bug 1874)
/ Play sample button now stops previous note even if mod is playing (bug 1366)
/ Sustain loop will now be enabled when setting it to sample selection.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/Ctrl_smp.cpp
trunk/OpenMPT/mptrack/Moddoc.cpp
trunk/OpenMPT/mptrack/View_smp.cpp
Modified: trunk/OpenMPT/mptrack/Ctrl_smp.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2008-10-13 17:28:21 UTC (rev 230)
+++ trunk/OpenMPT/mptrack/Ctrl_smp.cpp 2008-10-18 12:35:46 UTC (rev 231)
@@ -996,7 +996,9 @@
{
if ((m_pModDoc) && (m_pSndFile))
{
- if ((m_pSndFile->IsPaused()) && (m_pModDoc->IsNotePlaying(0, m_nSample, 0)))
+ // Fix (bug report 1366).
+ // if ((m_pSndFile->IsPaused()) && (m_pModDoc->IsNotePlaying(0, m_nSample, 0)))
+ if (m_pModDoc->IsNotePlaying(0, m_nSample, 0))
{
m_pModDoc->NoteOff(0, TRUE);
} else
@@ -2488,7 +2490,12 @@
if ((n >= 0) && (n < (LONG)pins->nLength) && ((n < (LONG)pins->nLoopEnd) || (!(pins->uFlags & CHN_LOOP))))
{
pins->nLoopStart = n;
- m_pModDoc->AdjustEndOfSample(m_nSample);
+ if(pins->uFlags & CHN_LOOP)
+ {
+ /* only update sample buffer if the loop is actually enabled
+ (resets sound without any reason otherwise) - bug report 1874 */
+ m_pModDoc->AdjustEndOfSample(m_nSample);
+ }
// 05/01/05 : ericus replaced "m_nSample << 24" by "m_nSample << 20" : 4000 samples -> 12bits [see Moddoc.h]
m_pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA, this);
m_pModDoc->SetModified();
@@ -2505,7 +2512,12 @@
if ((n >= 0) && (n <= (LONG)pins->nLength) && ((n > (LONG)pins->nLoopStart) || (!(pins->uFlags & CHN_LOOP))))
{
pins->nLoopEnd = n;
- m_pModDoc->AdjustEndOfSample(m_nSample);
+ if(pins->uFlags & CHN_LOOP)
+ {
+ /* only update sample buffer if the loop is actually enabled
+ (resets sound without any reason otherwise) - bug report 1874 */
+ m_pModDoc->AdjustEndOfSample(m_nSample);
+ }
// 05/01/05 : ericus replaced "m_nSample << 24" by "m_nSample << 20" : 4000 samples -> 12bits [see Moddoc.h]
m_pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA, this);
m_pModDoc->SetModified();
Modified: trunk/OpenMPT/mptrack/Moddoc.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Moddoc.cpp 2008-10-13 17:28:21 UTC (rev 230)
+++ trunk/OpenMPT/mptrack/Moddoc.cpp 2008-10-18 12:35:46 UTC (rev 231)
@@ -580,6 +580,7 @@
SetModified(FALSE);
m_bHasValidPath=true;
m_ShowSavedialog = false;
+ UpdateAllViews(NULL, HINT_MODGENERAL); // Update treeview (e.g. filename might have changed).
return TRUE;
} else
{
@@ -831,12 +832,15 @@
if (nVol >= 0) pChn->nVolume = nVol;
// handle sample looping.
- if ((loopstart + 16 < loopend) && (loopstart >= 0) && (loopend <= (LONG)pChn->nLength)) {
+ // Fix: Bug report 1700.
+ //if ((loopstart + 16 < loopend) && (loopstart >= 0) && (loopend <= (LONG)pChn->nLength)) {
+ if ((loopstart + 16 < loopend) && (loopstart >= 0) && (pChn->pInstrument != 0))
+ {
pChn->nPos = loopstart;
pChn->nPosLo = 0;
pChn->nLoopStart = loopstart;
pChn->nLoopEnd = loopend;
- pChn->nLength = loopend;
+ pChn->nLength = min(UINT(loopend), pChn->pInstrument->nLength);
}
// handle extra-loud flag
@@ -1960,7 +1964,7 @@
switch(m_SndFile.m_nTempoMode) {
case tempo_mode_alternative:
Message.Format("Using alternative tempo interpretation.\n\nAssuming:\n. %d ticks per second\n. %d ticks per row\n. %d rows per beat\nthe tempo is approximately: %.20g BPM",
- m_SndFile.m_nMusicTempo, m_SndFile.m_nMusicSpeed, CMainFrame::m_nRowSpacing2, bpm);
+ m_SndFile.m_nMusicTempo, m_SndFile.m_nMusicSpeed, m_SndFile.m_nRowsPerBeat, bpm);
break;
case tempo_mode_modern:
@@ -1970,7 +1974,7 @@
case tempo_mode_classic:
default:
Message.Format("Using standard tempo interpretation.\n\nAssuming:\n. A mod tempo (tick duration factor) of %d\n. %d ticks per row\n. %d rows per beat\nthe tempo is approximately: %.20g BPM",
- m_SndFile.m_nMusicTempo, m_SndFile.m_nMusicSpeed, CMainFrame::m_nRowSpacing2, bpm);
+ m_SndFile.m_nMusicTempo, m_SndFile.m_nMusicSpeed, m_SndFile.m_nRowsPerBeat, bpm);
break;
}
/*
Modified: trunk/OpenMPT/mptrack/View_smp.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_smp.cpp 2008-10-13 17:28:21 UTC (rev 230)
+++ trunk/OpenMPT/mptrack/View_smp.cpp 2008-10-18 12:35:46 UTC (rev 231)
@@ -1503,6 +1503,7 @@
{
pins->nSustainStart = m_dwBeginSel;
pins->nSustainEnd = m_dwEndSel;
+ pins->uFlags |= CHN_SUSTAINLOOP;
pModDoc->SetModified();
pModDoc->AdjustEndOfSample(m_nSample);
// 05/01/05 : ericus replaced "m_nSample << 24" by "m_nSample << 20" : 4000 samples -> 12bits [see Moddoc.h]
@@ -1914,9 +1915,9 @@
CModDoc *pModDoc = GetDocument();
if ((pModDoc) && (pMainFrm))
{
- if (note >= 0xFE)
+ if (note >= NOTE_NOTECUT)
{
- pModDoc->NoteOff(0, (note == 0xFE) ? TRUE : FALSE);
+ pModDoc->NoteOff(0, (note == NOTE_NOTECUT) ? TRUE : FALSE);
}
else
{
@@ -1926,7 +1927,9 @@
else
pModDoc->NoteOff(0, TRUE);
DWORD loopstart = m_dwBeginSel, loopend = m_dwEndSel;
- if (loopend - loopstart < (UINT)(4 << m_nZoom)) loopend = loopstart = 0;
+ if (loopend - loopstart < (UINT)(4 << m_nZoom))
+ loopend = loopstart = 0; // selection is too small -> no loop
+
pModDoc->PlayNote(note, 0, m_nSample, FALSE, -1, loopstart, loopend);
m_dwStatus |= SMPSTATUS_KEYDOWN;
s[0] = 0;
@@ -2148,7 +2151,12 @@
{
pins->nLoopStart = m_dwMenuParam;
pModDoc->SetModified();
- pModDoc->AdjustEndOfSample(m_nSample);
+ if(pins->uFlags & CHN_LOOP)
+ {
+ /* only update sample buffer if the loop is actually enabled
+ (resets sound without any reason otherwise) - bug report 1874 */
+ pModDoc->AdjustEndOfSample(m_nSample);
+ }
// 05/01/05 : ericus replaced "m_nSample << 24" by "m_nSample << 20" : 4000 samples -> 12bits [see Moddoc.h]
pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEINFO | HINT_SAMPLEDATA, NULL);
}
@@ -2168,7 +2176,12 @@
{
pins->nLoopEnd = m_dwMenuParam;
pModDoc->SetModified();
- pModDoc->AdjustEndOfSample(m_nSample);
+ if(pins->uFlags & CHN_LOOP)
+ {
+ /* only update sample buffer if the loop is actually enabled
+ (resets sound without any reason otherwise) - bug report 1874 */
+ pModDoc->AdjustEndOfSample(m_nSample);
+ }
// 05/01/05 : ericus replaced "m_nSample << 24" by "m_nSample << 20" : 4000 samples -> 12bits [see Moddoc.h]
pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEINFO | HINT_SAMPLEDATA, NULL);
}
@@ -2337,8 +2350,8 @@
case kcSampleNormalize: PostCtrlMessage(IDC_SAMPLE_NORMALIZE); return wParam;
case kcSampleAmplify: PostCtrlMessage(IDC_SAMPLE_AMPLIFY); return wParam;
- case kcNoteOff: PlayNote(255); return wParam;
- case kcNoteCut: PlayNote(254); return wParam;
+ case kcNoteOff: PlayNote(NOTE_KEYOFF); return wParam;
+ case kcNoteCut: PlayNote(NOTE_NOTECUT); return wParam;
}
if (wParam>=kcSampStartNotes && wParam<=kcSampEndNotes)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2008-10-13 17:28:29
|
Revision: 230
http://modplug.svn.sourceforge.net/modplug/?rev=230&view=rev
Author: relabsoluness
Date: 2008-10-13 17:28:21 +0000 (Mon, 13 Oct 2008)
Log Message:
-----------
(Patch from Jojo)
/ Sample editing: If possible, use loop points as trim limits if there's no selection chosen.
Modified Paths:
--------------
trunk/OpenMPT/mptrack/View_smp.cpp
Modified: trunk/OpenMPT/mptrack/View_smp.cpp
===================================================================
--- trunk/OpenMPT/mptrack/View_smp.cpp 2008-10-13 15:53:01 UTC (rev 229)
+++ trunk/OpenMPT/mptrack/View_smp.cpp 2008-10-13 17:28:21 UTC (rev 230)
@@ -1322,14 +1322,32 @@
m_dwMenuParam = dwPos;
}
}
+
if (m_dwBeginSel >= m_dwEndSel)
{
if (pins->uFlags & CHN_16BIT) ::AppendMenu(hMenu, MF_STRING, ID_SAMPLE_8BITCONVERT, "Convert to 8-bit");
if (pins->uFlags & CHN_STEREO) ::AppendMenu(hMenu, MF_STRING, ID_SAMPLE_MONOCONVERT, "Convert to mono");
}
+
+ // "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);
+
+ if ((m_dwBeginSel == m_dwEndSel) && (pins->nLoopStart < pins->nLoopEnd))
+ {
+ // no selection => use loop points
+ sTrimMenuText += " around loop points";
+ bIsGrayed = false;
+ }
- ::AppendMenu(hMenu, MF_STRING|(m_dwEndSel>m_dwBeginSel)?0:MF_GRAYED,
- ID_SAMPLE_TRIM, "Trim\t" + ih->GetKeyTextFromCommand(kcSampleTrim));
+ sTrimMenuText += "\t" + ih->GetKeyTextFromCommand(kcSampleTrim);
+
+ // change by jojo: "trim" menu item is also available
+ // if there's no selection, but loop points
+ //::AppendMenu(hMenu, MF_STRING|(m_dwEndSel>m_dwBeginSel)?0:MF_GRAYED,
+ // ID_SAMPLE_TRIM, "Trim\t" + ih->GetKeyTextFromCommand(kcSampleTrim));
+ ::AppendMenu(hMenu, MF_STRING|(bIsGrayed)?MF_GRAYED:0, ID_SAMPLE_TRIM, sTrimMenuText.c_str());
::AppendMenu(hMenu, MF_STRING, ID_EDIT_CUT, "Cut\t" + ih->GetKeyTextFromCommand(kcEditCut));
::AppendMenu(hMenu, MF_STRING, ID_EDIT_COPY, "Copy\t" + ih->GetKeyTextFromCommand(kcEditCopy));
}
@@ -1825,51 +1843,60 @@
//------------------------------
{
CModDoc *pModDoc = GetDocument();
+ //nothing loaded or invalid sample slot.
+ if(!pModDoc || m_nSample >= MAX_SAMPLES) return;
+
+ CSoundFile *pSndFile = pModDoc->GetSoundFile();
+ MODINSTRUMENT *pins = &pSndFile->Ins[m_nSample];
+
+ if(m_dwBeginSel == m_dwEndSel) {
+ // trim around loop points if there's no selection (suggested by jojo in topic 2258)
+ m_dwBeginSel = pins->nLoopStart;
+ m_dwEndSel = pins->nLoopEnd;
+ }
+
+ if (m_dwBeginSel >= m_dwEndSel) return; // invalid selection
+
BeginWaitCursor();
- if ((pModDoc) && (m_nSample < MAX_SAMPLES) && (m_dwBeginSel < m_dwEndSel))
+ UINT nStart = m_dwBeginSel;
+ UINT nEnd = m_dwEndSel - m_dwBeginSel;
+
+ if ((pins->pSample) && (nStart+nEnd <= pins->nLength) && (nEnd >= 16))
{
- CSoundFile *pSndFile = pModDoc->GetSoundFile();
- MODINSTRUMENT *pins = &pSndFile->Ins[m_nSample];
- UINT nStart = m_dwBeginSel;
- UINT nEnd = m_dwEndSel - m_dwBeginSel;
-
- if ((pins->pSample) && (nStart+nEnd <= pins->nLength) && (nEnd >= 16))
+ BEGIN_CRITICAL();
{
- BEGIN_CRITICAL();
+ UINT bend = nEnd, bstart = nStart;
+ if (pins->uFlags & CHN_16BIT) { bend <<= 1; bstart <<= 1; }
+ if (pins->uFlags & CHN_STEREO) { bend <<= 1; bstart <<= 1; }
+ signed char *p = (signed char *)pins->pSample;
+ for (UINT i=0; i<bend; i++)
{
- UINT bend = nEnd, bstart = nStart;
- if (pins->uFlags & CHN_16BIT) { bend <<= 1; bstart <<= 1; }
- if (pins->uFlags & CHN_STEREO) { bend <<= 1; bstart <<= 1; }
- signed char *p = (signed char *)pins->pSample;
- for (UINT i=0; i<bend; i++)
- {
- p[i] = p[i+bstart];
- }
+ p[i] = p[i+bstart];
}
- if (pins->nLoopStart >= nStart) pins->nLoopStart -= nStart;
- if (pins->nLoopEnd >= nStart) pins->nLoopEnd -= nStart;
- if (pins->nSustainStart >= nStart) pins->nSustainStart -= nStart;
- if (pins->nSustainEnd >= nStart) pins->nSustainEnd -= nStart;
- if (pins->nLoopEnd > nEnd) pins->nLoopEnd = nEnd;
- if (pins->nSustainEnd > nEnd) pins->nSustainEnd = nEnd;
- if (pins->nLoopStart >= pins->nLoopEnd)
- {
- pins->nLoopStart = pins->nLoopEnd = 0;
- pins->uFlags &= ~(CHN_LOOP|CHN_PINGPONGLOOP);
- }
- if (pins->nSustainStart >= pins->nSustainEnd)
- {
- pins->nSustainStart = pins->nSustainEnd = 0;
- pins->uFlags &= ~(CHN_SUSTAINLOOP|CHN_PINGPONGSUSTAIN);
- }
- pins->nLength = nEnd;
- END_CRITICAL();
- pModDoc->SetModified();
- pModDoc->AdjustEndOfSample(m_nSample);
- SetCurSel(0, 0);
- // 05/01/05 : ericus replaced "m_nSample << 24" by "m_nSample << 20" : 4000 samples -> 12bits [see Moddoc.h]
- pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA | HINT_SAMPLEINFO, NULL);
}
+ if (pins->nLoopStart >= nStart) pins->nLoopStart -= nStart;
+ if (pins->nLoopEnd >= nStart) pins->nLoopEnd -= nStart;
+ if (pins->nSustainStart >= nStart) pins->nSustainStart -= nStart;
+ if (pins->nSustainEnd >= nStart) pins->nSustainEnd -= nStart;
+ if (pins->nLoopEnd > nEnd) pins->nLoopEnd = nEnd;
+ if (pins->nSustainEnd > nEnd) pins->nSustainEnd = nEnd;
+ if (pins->nLoopStart >= pins->nLoopEnd)
+ {
+ pins->nLoopStart = pins->nLoopEnd = 0;
+ pins->uFlags &= ~(CHN_LOOP|CHN_PINGPONGLOOP);
+ }
+ if (pins->nSustainStart >= pins->nSustainEnd)
+ {
+ pins->nSustainStart = pins->nSustainEnd = 0;
+ pins->uFlags &= ~(CHN_SUSTAINLOOP|CHN_PINGPONGSUSTAIN);
+ }
+ pins->nLength = nEnd;
+ END_CRITICAL();
+ pModDoc->SetModified();
+ pModDoc->AdjustEndOfSample(m_nSample);
+ SetCurSel(0, 0);
+ // 05/01/05 : ericus replaced "m_nSample << 24" by "m_nSample << 20" : 4000 samples -> 12bits [see Moddoc.h]
+ pModDoc->UpdateAllViews(NULL, (m_nSample << HINT_SHIFT_SMP) | HINT_SAMPLEDATA | HINT_SAMPLEINFO, NULL);
}
EndWaitCursor();
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <rel...@us...> - 2008-10-13 15:53:25
|
Revision: 229
http://modplug.svn.sourceforge.net/modplug/?rev=229&view=rev
Author: relabsoluness
Date: 2008-10-13 15:53:01 +0000 (Mon, 13 Oct 2008)
Log Message:
-----------
(Patch from 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)
Modified Paths:
--------------
trunk/OpenMPT/mptrack/ChannelManagerDlg.cpp
trunk/OpenMPT/mptrack/Mptrack.cpp
Modified: trunk/OpenMPT/mptrack/ChannelManagerDlg.cpp
===================================================================
--- trunk/OpenMPT/mptrack/ChannelManagerDlg.cpp 2008-10-13 15:19:08 UTC (rev 228)
+++ trunk/OpenMPT/mptrack/ChannelManagerDlg.cpp 2008-10-13 15:53:01 UTC (rev 229)
@@ -596,7 +596,7 @@
HGDIOBJ oldfont = ::SelectObject(hdc, CMainFrame::GetGUIFont());
::SetTextColor(hdc, GetSysColor(bEnable || !bActivate ? COLOR_BTNTEXT : COLOR_GRAYTEXT));
- ::DrawText(hdc, lpszText, -1, &rect, dwFlags | DT_SINGLELINE);
+ ::DrawText(hdc, lpszText, -1, &rect, dwFlags | DT_SINGLELINE | DT_NOPREFIX);
::SelectObject(hdc, oldfont);
}
}
Modified: trunk/OpenMPT/mptrack/Mptrack.cpp
===================================================================
--- trunk/OpenMPT/mptrack/Mptrack.cpp 2008-10-13 15:19:08 UTC (rev 228)
+++ trunk/OpenMPT/mptrack/Mptrack.cpp 2008-10-13 15:53:01 UTC (rev 229)
@@ -1951,7 +1951,7 @@
::SetTextColor(hdc, GetSysColor((bDisabled) ? COLOR_GRAYTEXT : COLOR_BTNTEXT));
::SetBkMode(hdc, TRANSPARENT);
HGDIOBJ oldfont = ::SelectObject(hdc, CMainFrame::GetGUIFont());
- ::DrawText(hdc, lpszText, -1, &rect, dwFlags | DT_SINGLELINE);
+ ::DrawText(hdc, lpszText, -1, &rect, dwFlags | DT_SINGLELINE | DT_NOPREFIX);
::SelectObject(hdc, oldfont);
}
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
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-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] |