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:
parent
70504981a6
commit
3fc912710b
@ -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:
|
||||||
|
31
src/Mix.cpp
31
src/Mix.cpp
@ -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);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user