1
0
mirror of https://github.com/cookiengineer/audacity synced 2025-06-17 08:30:06 +02:00

Leland's minimal_v2.patch for bug 650

This commit is contained in:
v.audacity 2013-09-16 02:32:43 +00:00
parent 70504981a6
commit 3fc912710b
3 changed files with 101 additions and 12 deletions

View File

@ -69,6 +69,74 @@ const float Dither::SHAPED_BS[] = { 2.033f, -2.165f, 1.959f, -1.590f, 0.6149f };
// except the branches for clipping the sample, and therefore should // except the branches for clipping the sample, and therefore should
// be quite fast. // be quite fast.
#if 0
// To assist in understanding what the macros are doing, here's an example of what
// the result would be for Shaped dither:
//
// DITHER(ShapedDither, dest, destFormat, source, sourceFormat, len, stride);
do {
if (sourceFormat == int24Sample && destFormat == int16Sample)
do {
char *d, *s;
unsigned int i;
int x;
for (d = (char*)dest, s = (char*)source, i = 0; i < len; i++, d += (int16Sample >> 16) * stride, s += (int24Sample >> 16) * stride)
do {
x = lrintf((ShapedDither((((*(( int*)(s)) / float(1<<23))) * float(1<<15)))));
if (x>(32767))
*((short*)((((d)))))=(32767);
else if (x<(-32768))
*((short*)((((d)))))=(-32768);
else
*((short*)((((d)))))=(short)x;
} while (0);
} while (0);
else if (sourceFormat == floatSample && destFormat == int16Sample)
do {
char *d, *s;
unsigned int i;
int x;
for (d = (char*)dest, s = (char*)source, i = 0; i < len; i++, d += (int16Sample >> 16) * stride, s += (floatSample >> 16) * stride)
do {
x = lrintf((ShapedDither((((*((float*)(s)) > 1.0 ? 1.0 :
*((float*)(s)) < -1.0 ? -1.0 :
*((float*)(s)))) * float(1<<15)))));
if (x>(32767))
*((short*)((((d)))))=(32767);
else if (x<(-32768))
*((short*)((((d)))))=(-32768);
else
*((short*)((((d)))))=(short)x;
} while (0);
} while (0);
else if (sourceFormat == floatSample && destFormat == int24Sample)
do {
char *d, *s;
unsigned int i;
int x;
for (d = (char*)dest, s = (char*)source, i = 0; i < len; i++, d += (int24Sample >> 16) * stride, s += (floatSample >> 16) * stride)
do {
x = lrintf((ShapedDither((((*((float*)(s)) > 1.0 ? 1.0 :
*((float*)(s)) < -1.0 ? -1.0 :
*((float*)(s)))) * float(1<<23)))));
if (x>(8388607))
*((int*)((((d)))))=(8388607);
else if (x<(-8388608))
*((int*)((((d)))))=(-8388608);
else
*((int*)((((d)))))=(int)x;
} while (0);
} while (0);
else {
if ( false )
;
else
wxOnAssert(L"c:\\audacity\\src\\dither.cpp", 252, __FUNCTION__ , L"false", 0);
}
} while (0);
#endif
// Defines for sample conversion // Defines for sample conversion
#define CONVERT_DIV16 float(1<<15) #define CONVERT_DIV16 float(1<<15)
#define CONVERT_DIV24 float(1<<23) #define CONVERT_DIV24 float(1<<23)
@ -118,7 +186,7 @@ const float Dither::SHAPED_BS[] = { 2.033f, -2.165f, 1.959f, -1.590f, 0.6149f };
int x; \ int x; \
for (d = (char*)dst, s = (char*)src, i = 0; \ for (d = (char*)dst, s = (char*)src, i = 0; \
i < len; \ i < len; \
i++, d += SAMPLE_SIZE(dstFormat), \ i++, d += SAMPLE_SIZE(dstFormat) * stride, \
s += SAMPLE_SIZE(srcFormat) * stride) \ s += SAMPLE_SIZE(srcFormat) * stride) \
DITHER_STEP(dither, store, load, d, s); \ DITHER_STEP(dither, store, load, d, s); \
} while (0) } while (0)
@ -196,7 +264,7 @@ void Dither::Apply(enum DitherType ditherType,
{ {
memcpy(d, s, srcBytes); memcpy(d, s, srcBytes);
s += stride * srcBytes; s += stride * srcBytes;
d += srcBytes; d += stride * srcBytes;
} }
} }
@ -210,13 +278,13 @@ void Dither::Apply(enum DitherType ditherType,
if (sourceFormat == int16Sample) if (sourceFormat == int16Sample)
{ {
short* s = (short*)source; short* s = (short*)source;
for (i = 0; i < len; i++, d++, s+= stride) for (i = 0; i < len; i++, d += stride, s += stride)
*d = FROM_INT16(s); *d = FROM_INT16(s);
} else } else
if (sourceFormat == int24Sample) if (sourceFormat == int24Sample)
{ {
int* s = (int*)source; int* s = (int*)source;
for (i = 0; i < len; i++, d++, s+= stride) for (i = 0; i < len; i++, d += stride, s += stride)
*d = FROM_INT24(s); *d = FROM_INT24(s);
} else { } else {
wxASSERT(false); // source format unknown wxASSERT(false); // source format unknown
@ -231,7 +299,7 @@ void Dither::Apply(enum DitherType ditherType,
{ {
*d = ((int)*s) << 8; *d = ((int)*s) << 8;
s += stride; s += stride;
d++; d += stride;
} }
} else } else
{ {
@ -245,10 +313,11 @@ void Dither::Apply(enum DitherType ditherType,
DITHER(RectangleDither, dest, destFormat, source, sourceFormat, len, stride); DITHER(RectangleDither, dest, destFormat, source, sourceFormat, len, stride);
break; break;
case triangle: case triangle:
Reset(); // Reset dither filter for this new conversion.
DITHER(TriangleDither, dest, destFormat, source, sourceFormat, len, stride); DITHER(TriangleDither, dest, destFormat, source, sourceFormat, len, stride);
break; break;
case shaped: case shaped:
Reset(); // reset shaped dither filter for this new conversion Reset(); // Reset dither filter for this new conversion.
DITHER(ShapedDither, dest, destFormat, source, sourceFormat, len, stride); DITHER(ShapedDither, dest, destFormat, source, sourceFormat, len, stride);
break; break;
default: default:

View File

@ -235,6 +235,7 @@ Mixer::Mixer(int numInputTracks, WaveTrack **inputTracks,
{ {
int i; int i;
mHighQuality = highQuality;
mNumInputTracks = numInputTracks; mNumInputTracks = numInputTracks;
mInputTrack = new WaveTrack*[mNumInputTracks]; mInputTrack = new WaveTrack*[mNumInputTracks];
mSamplePos = new sampleCount[mNumInputTracks]; mSamplePos = new sampleCount[mNumInputTracks];
@ -287,11 +288,11 @@ Mixer::Mixer(int numInputTracks, WaveTrack **inputTracks,
double factor = (mRate / mInputTrack[i]->GetRate()); double factor = (mRate / mInputTrack[i]->GetRate());
if (timeTrack) { if (timeTrack) {
// variable rate resampling // variable rate resampling
mResample[i] = new Resample(highQuality, mResample[i] = new Resample(mHighQuality,
factor / timeTrack->GetRangeUpper(), factor / timeTrack->GetRangeUpper(),
factor / timeTrack->GetRangeLower()); factor / timeTrack->GetRangeLower());
} else { } else {
mResample[i] = new Resample(highQuality, factor, factor); // constant rate resampling mResample[i] = new Resample(mHighQuality, factor, factor); // constant rate resampling
} }
mSampleQueue[i] = new float[mQueueMaxLen]; mSampleQueue[i] = new float[mQueueMaxLen];
mQueueStart[i] = 0; mQueueStart[i] = 0;
@ -595,10 +596,28 @@ sampleCount Mixer::Process(sampleCount maxToProcess)
mTime = std::min(t, mT1); mTime = std::min(t, mT1);
} }
out = mInterleaved ? maxOut * mNumChannels : maxOut; if(mInterleaved) {
for(int c=0; c<mNumBuffers; c++) for(int c=0; c<mNumChannels; c++) {
CopySamples(mTemp[c], floatSample, mBuffer[c], mFormat, out); CopySamples(mTemp[0] + (c * SAMPLE_SIZE(floatSample)),
floatSample,
mBuffer[0] + (c * SAMPLE_SIZE(mFormat)),
mFormat,
maxOut,
mHighQuality,
mNumChannels);
}
}
else {
for(int c=0; c<mNumBuffers; c++) {
CopySamples(mTemp[c],
floatSample,
mBuffer[c],
mFormat,
maxOut,
mHighQuality,
1);
}
}
// MB: this doesn't take warping into account, replaced with code based on mSamplePos // MB: this doesn't take warping into account, replaced with code based on mSamplePos
//mT += (maxOut / mRate); //mT += (maxOut / mRate);

View File

@ -157,6 +157,7 @@ class AUDACITY_DLL_API Mixer {
samplePtr *mTemp; samplePtr *mTemp;
float *mFloatBuffer; float *mFloatBuffer;
double mRate; double mRate;
bool mHighQuality;
}; };
#endif #endif