ref: 12d7414f7ece191783e54d92beb46e0e182202f6
parent: e0066b4725069ce120acde8d584ade9bc2d3d0cf
author: Krzysztof Nikiel <knik@users.sourceforge.net>
date: Mon Oct 30 09:25:49 EDT 2017
initial implementation of Intensity Stereo coding
--- a/frontend/main.c
+++ b/frontend/main.c
@@ -94,6 +94,7 @@
HELP_IO,
HELP_MP4,
HELP_ADVANCED,
+ OPT_JOINT
};
typedef struct {
@@ -183,7 +184,9 @@
static help_t help_advanced[] = {
{"--tns \tEnable coding of TNS, temporal noise shaping.\n"},
{"--no-tns\tDisable coding of TNS, temporal noise shaping.\n"},
- {"--no-midside\tDon\'t use mid/side coding.\n"},
+ {"--joint 0\tDisable joint stereo coding.\n"},
+ {"--joint 1\tUse mid/side coding.\n"},
+ {"--joint 2\tUse intensity stereo coding.\n"},
{"--mpeg-vers X\tForce AAC MPEG version, X can be 2 or 4\n"},
{"--shortctl X\tEnforce block type (0 = both (default); 1 = no short; 2 = no\n"
"\t\tlong).\n"},
@@ -421,7 +424,7 @@
faacEncConfigurationPtr myFormat;
unsigned int mpegVersion = MPEG2;
unsigned int objectType = LOW;
- static int useMidSide = 1;
+ static int jointmode = JOINT_IS;
static int useTns = 0;
enum container_format container = NO_CONTAINER;
enum stream_format stream = ADTS_STREAM;
@@ -505,7 +508,7 @@
{"help-mp4", 0, 0, HELP_MP4},
{"help-advanced", 0, 0, HELP_ADVANCED},
{"raw", 0, 0, 'r'},
- {"no-midside", 0, &useMidSide, 0},
+ {"joint", required_argument, 0, OPT_JOINT},
{"cutoff", 1, 0, 'c'},
{"quality", 1, 0, 'q'},
{"pcmraw", 0, 0, 'P'},
@@ -749,6 +752,9 @@
help(c);
return 1;
break;
+ case OPT_JOINT:
+ jointmode = atoi(optarg);
+ break;
case '?':
default:
help('?');
@@ -885,7 +891,7 @@
}
if (infile->channels >= 6)
myFormat->useLfe = 1;
- myFormat->allowMidside = useMidSide;
+ myFormat->jointmode = jointmode;
if (quantqual > 0)
{
myFormat->quantqual = quantqual;
@@ -968,8 +974,15 @@
fprintf(stderr, "(MPEG-%d)", (mpegVersion == MPEG4) ? 4 : 2);
if (myFormat->useTns)
fprintf(stderr, " + TNS");
- if (myFormat->allowMidside)
+
+ switch(myFormat->jointmode) {
+ case JOINT_MS:
fprintf(stderr, " + M/S");
+ break;
+ case JOINT_IS:
+ fprintf(stderr, " + IS");
+ break;
+ }
fprintf(stderr, "\n");
fprintf(stderr, "Container format: ");
--- a/include/faaccfg.h
+++ b/include/faaccfg.h
@@ -22,7 +22,7 @@
#ifndef _FAACCFG_H_
#define _FAACCFG_H_
-#define FAAC_CFG_VERSION 104
+#define FAAC_CFG_VERSION 105
/* MPEG ID's */
#define MPEG2 1
@@ -51,6 +51,8 @@
ADTS_STREAM = 1,
};
+enum {JOINT_NONE = 0, JOINT_MS, JOINT_IS};
+
#pragma pack(push, 1)
typedef struct faacEncConfiguration
{
@@ -69,8 +71,8 @@
/* AAC object type */
unsigned int aacObjectType;
- /* Allow mid/side coding */
- unsigned int allowMidside;
+ /* Joint coding mode */
+ unsigned int jointmode;
/* Use one of the channels as LFE channel */
unsigned int useLfe;
--- a/libfaac/Makefile.am
+++ b/libfaac/Makefile.am
@@ -1,5 +1,5 @@
-common_SOURCES = bitstream.c fft.c frame.c midside.c blockswitch.c util.c channels.c filtbank.c tns.c quantize.c huff2.c huffdata.c
-common_INCLUDES = channels.h filtbank.h blockswitch.h coder.h frame.h midside.h tns.h bitstream.h fft.h util.h quantize.h version.h huffdata.h huff2.h
+common_SOURCES = bitstream.c fft.c frame.c blockswitch.c util.c channels.c filtbank.c tns.c quantize.c huff2.c huffdata.c stereo.c
+common_INCLUDES = channels.h filtbank.h blockswitch.h coder.h frame.h tns.h bitstream.h fft.h util.h quantize.h version.h huffdata.h huff2.h stereo.h
common_LIBADD = -lm
common_CFLAGS = -fvisibility=hidden
if CPUSSE
--- a/libfaac/frame.c
+++ b/libfaac/frame.c
@@ -25,23 +25,18 @@
#include "frame.h"
#include "coder.h"
-#include "midside.h"
#include "channels.h"
#include "bitstream.h"
#include "filtbank.h"
#include "util.h"
#include "tns.h"
-#include "version.h"
+#include "stereo.h"
-#if FAAC_RELEASE
-static char *libfaacName = FAAC_VERSION;
-#else
-static char *libfaacName = FAAC_VERSION ".1 (" __DATE__ ") UNSTABLE";
-#endif
+static char *libfaacName = PACKAGE_VERSION;
static char *libCopyright =
- "FAAC - Freeware Advanced Audio Coder (http://www.audiocoding.com/)\n"
+ "FAAC - Freeware Advanced Audio Coder (http://faac.sourceforge.net/)\n"
" Copyright (C) 1999,2000,2001 Menno Bakker\n"
- " Copyright (C) 2002,2003 Krzysztof Nikiel\n"
+ " Copyright (C) 2002,2003,2017 Krzysztof Nikiel\n"
"This software is based on the ISO MPEG-4 reference source code.\n";
static const psymodellist_t psymodellist[] = {
@@ -117,7 +112,7 @@
int i;
int maxqual = hEncoder->config.outputFormat ? MAXQUALADTS : MAXQUAL;
- hEncoder->config.allowMidside = config->allowMidside;
+ hEncoder->config.jointmode = config->jointmode;
hEncoder->config.useLfe = config->useLfe;
hEncoder->config.useTns = config->useTns;
hEncoder->config.aacObjectType = config->aacObjectType;
@@ -256,7 +251,7 @@
hEncoder->config.copyright = libCopyright;
hEncoder->config.mpegVersion = MPEG4;
hEncoder->config.aacObjectType = LOW;
- hEncoder->config.allowMidside = 1;
+ hEncoder->config.jointmode = JOINT_IS;
hEncoder->config.useLfe = 1;
hEncoder->config.useTns = 0;
hEncoder->config.bitRate = 64000;
@@ -368,7 +363,7 @@
unsigned int numChannels = hEncoder->numChannels;
unsigned int useLfe = hEncoder->config.useLfe;
unsigned int useTns = hEncoder->config.useTns;
- unsigned int allowMidside = hEncoder->config.allowMidside;
+ unsigned int jointmode = hEncoder->config.jointmode;
unsigned int bandWidth = hEncoder->config.bandWidth;
unsigned int shortctl = hEncoder->config.shortctl;
int maxqual = hEncoder->config.outputFormat ? MAXQUALADTS : MAXQUAL;
@@ -564,12 +559,8 @@
}
}
- if (allowMidside)
- MSEncode(coderInfo, channelInfo, hEncoder->freqBuff, numChannels,
- (double)hEncoder->aacquantCfg.quality/DEFQUAL);
- else
- MSEncode(coderInfo, channelInfo, hEncoder->freqBuff, numChannels,
- 0.0);
+ AACstereo(coderInfo, channelInfo, hEncoder->freqBuff, numChannels,
+ (double)hEncoder->aacquantCfg.quality/DEFQUAL, jointmode);
#ifdef DRM
/* loop the quantization until the desired bit-rate is reached */
--- a/libfaac/huff2.c
+++ b/libfaac/huff2.c
@@ -95,9 +95,9 @@
switch (bnum)
{
#ifdef DRM
- case ZERO_HCB:
- case INTENSITY_HCB:
- case INTENSITY_HCB2:
+ case HCB_ZERO:
+ case HCB_INTENSITY:
+ case HCB_INTENSITY2:
for(ofs = 0; ofs < len; ofs += 4)
{
coder->s[datacnt].data = 0;
@@ -241,7 +241,7 @@
bits += blen;
}
break;
- case ESC_HCB:
+ case HCB_ESC:
for(ofs = 0; ofs < len; ofs += 2)
{
int x0, x1;
@@ -397,7 +397,7 @@
if (maxq < 1)
{
- bookmin = ZERO_HCB;
+ bookmin = HCB_ZERO;
lenmin = 0;
}
else if (maxq < 2)
@@ -422,7 +422,7 @@
}
else
{
- bookmin = ESC_HCB;
+ bookmin = HCB_ESC;
}
#ifdef DRM
@@ -431,7 +431,7 @@
if (vcb11)
bookmin = vcb11;
#else
- if (bookmin > ZERO_HCB)
+ if (bookmin > HCB_ZERO)
huffcode(qs, len, bookmin, coder);
#endif
coder->book[coder->bandcnt] = bookmin;
@@ -522,7 +522,7 @@
{
int book = coder->book[cnt];
- if ((book == INTENSITY_HCB) || (book== INTENSITY_HCB2))
+ if ((book == HCB_INTENSITY) || (book== HCB_INTENSITY2))
{
diff = coder->sf[cnt] - lastis;
if (diff > 60)
--- a/libfaac/huff2.h
+++ b/libfaac/huff2.h
@@ -20,10 +20,11 @@
#include "bitstream.h"
enum {
- ZERO_HCB = 0,
- ESC_HCB = 11,
- INTENSITY_HCB = 15,
- INTENSITY_HCB2 = 14,
+ HCB_ZERO = 0,
+ HCB_ESC = 11,
+ HCB_INTENSITY2 = 14,
+ HCB_INTENSITY = 15,
+ HCB_NONE
};
int huffbook(CoderInfo *coderInfo,
--- a/libfaac/midside.c
+++ /dev/null
@@ -1,213 +1,0 @@
-/*
- * FAAC - Freeware Advanced Audio Coder
- * Copyright (C) 2003 Krzysztof Nikiel
- *
- * 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 "channels.h"
-#include "util.h"
-
-
-static void midside(CoderInfo *coder, ChannelInfo *channel,
- double *sl0, double *sr0, int *mscnt,
- int wstart, int wend,
- double thrmid, double thrside
- )
-{
- int sfb;
- int win;
-
- for (sfb = 0; sfb < coder->sfbn; sfb++)
- {
- int ms = 0;
- int l, start, end;
- double sum, diff;
- double enrgs, enrgd, enrgl, enrgr;
-
- if (sfb < 1)
- goto setms;
-
- start = coder->sfb_offset[sfb];
- end = coder->sfb_offset[sfb + 1];
-
- enrgs = enrgd = enrgl = enrgr = 0.0;
- for (win = wstart; win < wend; win++)
- {
- double *sl = sl0 + win * BLOCK_LEN_SHORT;
- double *sr = sr0 + win * BLOCK_LEN_SHORT;
-
- for (l = start; l < end; l++)
- {
- double lx = sl[l];
- double rx = sr[l];
-
- sum = 0.5 * (lx + rx);
- diff = 0.5 * (lx - rx);
-
- enrgs += sum * sum;
- enrgd += diff * diff;
- enrgl += lx * lx;
- enrgr += rx * rx;
- }
- }
-
- if ((min(enrgl, enrgr) * thrmid) >= max(enrgs, enrgd))
- {
- enum {PH_NONE, PH_IN, PH_OUT};
- int phase = PH_NONE;
-
- if ((enrgs * thrmid * 2.0) >= (enrgl + enrgr))
- {
- ms = 1;
- phase = PH_IN;
- }
- else if ((enrgd * thrmid * 2.0) >= (enrgl + enrgr))
- {
- ms = 1;
- phase = PH_OUT;
- }
-
- if (ms)
- {
- for (win = wstart; win < wend; win++)
- {
- double *sl = sl0 + win * BLOCK_LEN_SHORT;
- double *sr = sr0 + win * BLOCK_LEN_SHORT;
- for (l = start; l < end; l++)
- {
- if (phase == PH_IN)
- {
- sum = sl[l] + sr[l];
- diff = 0;
- }
- else
- {
- sum = 0;
- diff = sl[l] - sr[l];
- }
-
- sl[l] = 0.5 * sum;
- sr[l] = 0.5 * diff;
- }
- }
- }
- }
-
- if (min(enrgl, enrgr) <= (thrside * max(enrgl, enrgr)))
- {
- for (win = wstart; win < wend; win++)
- {
- double *sl = sl0 + win * BLOCK_LEN_SHORT;
- double *sr = sr0 + win * BLOCK_LEN_SHORT;
- for (l = start; l < end; l++)
- {
- if (enrgl < enrgr)
- sl[l] = 0.0;
- else
- sr[l] = 0.0;
- }
- }
- }
-
- setms:
- channel->msInfo.ms_used[*mscnt] = ms;
- (*mscnt)++;
- }
-}
-
-
-void MSEncode(CoderInfo *coder,
- ChannelInfo *channel,
- double *s[MAX_CHANNELS],
- int maxchan,
- double quality)
-{
- int chn;
- int usems;
- static const double thr075 = 1.09 /* ~0.75dB */ - 1.0;
- static const double thrmax = 1.25 /* ~2dB */ - 1.0;
- static const double sidemin = 0.1; /* -20dB */
- static const double sidemax = 0.3; /* ~-10.5dB */
- double thrmid, thrside;
-
- if (quality > 0.01)
- {
- usems = 1;
- thrmid = thr075 / quality;
- if (thrmid > thrmax)
- thrmid = thrmax;
-
- thrside = sidemin / quality;
- if (thrside > sidemax)
- thrside = sidemax;
- }
- else
- {
- usems = 0;
- thrmid = 0.0;
- thrside = 0.0;
- }
- thrmid += 1.0;
-
- // convert into energy
- thrmid *= thrmid;
- thrside *= thrside;
-
- for (chn = 0; chn < maxchan; chn++)
- {
- int rch;
- int cnt;
- int group;
- int mscnt = 0;
- int start = 0;
-
- if (!channel[chn].present)
- continue;
- if (!((channel[chn].cpe) && (channel[chn].ch_is_left)))
- continue;
-
- rch = channel[chn].paired_ch;
-
- channel[chn].msInfo.is_present = 0;
- channel[rch].msInfo.is_present = 0;
-
- if (!usems)
- continue;
-
- if (coder[chn].block_type != coder[rch].block_type)
- continue;
- if (coder[chn].groups.n != coder[rch].groups.n)
- continue;
- for (cnt = 0; cnt < coder[chn].groups.n; cnt++)
- if (coder[chn].groups.len[cnt] != coder[rch].groups.len[cnt])
- goto skip;
-
- channel[chn].common_window = 1;
- channel[chn].msInfo.is_present = 1;
- channel[rch].msInfo.is_present = 1;
-
- for (group = 0; group < coder->groups.n; group++)
- {
- int end = start + coder->groups.len[group];
- midside(coder + chn, channel + chn, s[chn], s[rch], &mscnt,
- start, end, thrmid, thrside);
- start = end;
- }
- skip:;
- }
-}
--- a/libfaac/midside.h
+++ /dev/null
@@ -1,39 +1,0 @@
-/*
- * FAAC - Freeware Advanced Audio Coder
- * Copyright (C) 2003 Krzysztof Nikiel
- *
- * 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
- *
- * $Id: midside.h,v 1.1 2003/06/26 19:40:23 knik Exp $
- */
-
-#ifndef _MIDSIDE_H
-#define _MIDSIDE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
-
-#include "coder.h"
-
-
-void MSEncode(CoderInfo *coderInfo, ChannelInfo *channelInfo, double *spectrum[MAX_CHANNELS],
- unsigned int numberOfChannels, double quality);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* _MIDSIDE_H */
--- a/libfaac/quantize.c
+++ b/libfaac/quantize.c
@@ -179,6 +179,17 @@
const double *xr;
int win;
+ if (coderInfo->book[coderInfo->bandcnt] != HCB_NONE)
+ {
+#if 0
+ int book = coderInfo->book[coderInfo->bandcnt];
+ if ((book != HCB_INTENSITY) && (book != HCB_INTENSITY2))
+ printf("book[%d]:%d\n",coderInfo->bandcnt, book);
+#endif
+ coderInfo->bandcnt++;
+ continue;
+ }
+
start = coderInfo->sfb_offset[sb];
end = coderInfo->sfb_offset[sb+1];
@@ -198,8 +209,12 @@
if ((rmsx < NOISEFLOOR) || (!bandqual[sb]))
{
- coderInfo->book[coderInfo->bandcnt] = ZERO_HCB;
+#if 0
+ coderInfo->book[coderInfo->bandcnt] = HCB_ZERO;
coderInfo->sf[coderInfo->bandcnt++] = 0;
+#else
+ coderInfo->book[coderInfo->bandcnt++] = HCB_ZERO;
+#endif
continue;
}
@@ -258,7 +273,7 @@
xr += BLOCK_LEN_SHORT;
}
huffbook(coderInfo, xitab, gsize * end);
- coderInfo->sf[coderInfo->bandcnt++] = SF_OFFSET - sfac;
+ coderInfo->sf[coderInfo->bandcnt++] += SF_OFFSET - sfac;
}
}
@@ -269,8 +284,10 @@
double *gxr;
coder->global_gain = 0;
+#if 0
for (cnt = 0; cnt < coder->sfbn; cnt++)
- coder->sf[cnt] = 0;
+ coder->sf[cnt] = SF_OFFSET;
+#endif
coder->bandcnt = 0;
coder->datacnt = 0;
@@ -299,7 +316,7 @@
int book = coder->book[cnt];
if (!book)
continue;
- if ((book != INTENSITY_HCB) && (book != INTENSITY_HCB2))
+ if ((book != HCB_INTENSITY) && (book != HCB_INTENSITY2))
{
coder->global_gain = coder->sf[cnt];
break;
@@ -312,7 +329,7 @@
for (cnt = 0; cnt < coder->bandcnt; cnt++)
{
int book = coder->book[cnt];
- if ((book == INTENSITY_HCB) || (book == INTENSITY_HCB2))
+ if ((book == HCB_INTENSITY) || (book == HCB_INTENSITY2))
{
int diff = coder->sf[cnt] - lastis;
--- /dev/null
+++ b/libfaac/stereo.c
@@ -1,0 +1,366 @@
+/****************************************************************************
+ Intensity Stereo
+
+ Copyright (C) 2017 Krzysztof Nikiel
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+****************************************************************************/
+
+#include <math.h>
+#include "stereo.h"
+#include "huff2.h"
+
+
+static void stereo(CoderInfo *cl, CoderInfo *cr,
+ double *sl0, double *sr0, int *sfcnt,
+ int wstart, int wend, double phthr
+ )
+{
+ int sfb;
+ int win;
+
+ if (!phthr)
+ return;
+
+ phthr = 1.0 / phthr;
+
+ for (sfb = 0; sfb < cl->sfbn; sfb++)
+ {
+ int l, start, end;
+ double sum, diff;
+ double enrgs, enrgd, enrgl, enrgr;
+ int hcb = HCB_NONE;
+ const double step = 10/1.50515;
+ double ethr;
+ double vfix, efix;
+
+#if 1
+ if (sfb < 1)
+ {
+ (*sfcnt)++;
+ continue;
+ }
+#endif
+
+ start = cl->sfb_offset[sfb];
+ end = cl->sfb_offset[sfb + 1];
+
+ enrgs = enrgd = enrgl = enrgr = 0.0;
+ for (win = wstart; win < wend; win++)
+ {
+ double *sl = sl0 + win * BLOCK_LEN_SHORT;
+ double *sr = sr0 + win * BLOCK_LEN_SHORT;
+
+ for (l = start; l < end; l++)
+ {
+ double lx = sl[l];
+ double rx = sr[l];
+
+ sum = lx + rx;
+ diff = lx - rx;
+
+ enrgs += sum * sum;
+ enrgd += diff * diff;
+ enrgl += lx * lx;
+ enrgr += rx * rx;
+ }
+ }
+
+ ethr = sqrt(enrgl) + sqrt(enrgr);
+ ethr *= ethr;
+ ethr *= phthr;
+ efix = enrgl + enrgr;
+ if (enrgs >= ethr)
+ {
+ hcb = HCB_INTENSITY;
+ vfix = sqrt(efix / enrgs);
+ }
+ else if (enrgd >= ethr)
+ {
+ hcb = HCB_INTENSITY2;
+ vfix = sqrt(efix / enrgd);
+ }
+
+ if (hcb != HCB_NONE)
+ {
+ int sf = lrint(log10(enrgl / efix) * step);
+ int pan = lrint(log10(enrgr/efix) * step) - sf;
+
+ if (pan > 30)
+ {
+ cl->book[*sfcnt] = HCB_ZERO;
+ (*sfcnt)++;
+ continue;
+ }
+ if (pan < -30)
+ {
+ cr->book[*sfcnt] = HCB_ZERO;
+ (*sfcnt)++;
+ continue;
+ }
+ cl->sf[*sfcnt] = sf;
+ cr->sf[*sfcnt] = -pan;
+ cr->book[*sfcnt] = hcb;
+
+ for (win = wstart; win < wend; win++)
+ {
+ double *sl = sl0 + win * BLOCK_LEN_SHORT;
+ double *sr = sr0 + win * BLOCK_LEN_SHORT;
+ for (l = start; l < end; l++)
+ {
+ if (hcb == HCB_INTENSITY)
+ sum = sl[l] + sr[l];
+ else
+ sum = sl[l] - sr[l];
+
+ sl[l] = sum * vfix;
+ }
+ }
+ }
+ (*sfcnt)++;
+ }
+}
+
+static void midside(CoderInfo *coder, ChannelInfo *channel,
+ double *sl0, double *sr0, int *sfcnt,
+ int wstart, int wend,
+ double thrmid, double thrside
+ )
+{
+ int sfb;
+ int win;
+
+ for (sfb = 0; sfb < coder->sfbn; sfb++)
+ {
+ int ms = 0;
+ int l, start, end;
+ double sum, diff;
+ double enrgs, enrgd, enrgl, enrgr;
+
+ if (sfb < 1)
+ goto setms;
+
+ start = coder->sfb_offset[sfb];
+ end = coder->sfb_offset[sfb + 1];
+
+ enrgs = enrgd = enrgl = enrgr = 0.0;
+ for (win = wstart; win < wend; win++)
+ {
+ double *sl = sl0 + win * BLOCK_LEN_SHORT;
+ double *sr = sr0 + win * BLOCK_LEN_SHORT;
+
+ for (l = start; l < end; l++)
+ {
+ double lx = sl[l];
+ double rx = sr[l];
+
+ sum = 0.5 * (lx + rx);
+ diff = 0.5 * (lx - rx);
+
+ enrgs += sum * sum;
+ enrgd += diff * diff;
+ enrgl += lx * lx;
+ enrgr += rx * rx;
+ }
+ }
+
+ if ((min(enrgl, enrgr) * thrmid) >= max(enrgs, enrgd))
+ {
+ enum {PH_NONE, PH_IN, PH_OUT};
+ int phase = PH_NONE;
+
+ if ((enrgs * thrmid * 2.0) >= (enrgl + enrgr))
+ {
+ ms = 1;
+ phase = PH_IN;
+ }
+ else if ((enrgd * thrmid * 2.0) >= (enrgl + enrgr))
+ {
+ ms = 1;
+ phase = PH_OUT;
+ }
+
+ if (ms)
+ {
+ for (win = wstart; win < wend; win++)
+ {
+ double *sl = sl0 + win * BLOCK_LEN_SHORT;
+ double *sr = sr0 + win * BLOCK_LEN_SHORT;
+ for (l = start; l < end; l++)
+ {
+ if (phase == PH_IN)
+ {
+ sum = sl[l] + sr[l];
+ diff = 0;
+ }
+ else
+ {
+ sum = 0;
+ diff = sl[l] - sr[l];
+ }
+
+ sl[l] = 0.5 * sum;
+ sr[l] = 0.5 * diff;
+ }
+ }
+ }
+ }
+
+ if (min(enrgl, enrgr) <= (thrside * max(enrgl, enrgr)))
+ {
+ for (win = wstart; win < wend; win++)
+ {
+ double *sl = sl0 + win * BLOCK_LEN_SHORT;
+ double *sr = sr0 + win * BLOCK_LEN_SHORT;
+ for (l = start; l < end; l++)
+ {
+ if (enrgl < enrgr)
+ sl[l] = 0.0;
+ else
+ sr[l] = 0.0;
+ }
+ }
+ }
+
+ setms:
+ channel->msInfo.ms_used[*sfcnt] = ms;
+ (*sfcnt)++;
+ }
+}
+
+
+void AACstereo(CoderInfo *coder,
+ ChannelInfo *channel,
+ double *s[MAX_CHANNELS],
+ int maxchan,
+ double quality,
+ int mode
+ )
+{
+ int chn;
+ static const double thr075 = 1.09 /* ~0.75dB */ - 1.0;
+ static const double thrmax = 1.25 /* ~2dB */ - 1.0;
+ static const double sidemin = 0.1; /* -20dB */
+ static const double sidemax = 0.3; /* ~-10.5dB */
+ static const double isthrmax = sqrt(2) - 1.0;
+ double thrmid, thrside;
+ double isthr;
+
+ thrmid = 1.0;
+ thrside = 0.0;
+ isthr = 1.0;
+
+ switch (mode)
+ {
+ case JOINT_MS:
+ thrmid = thr075 / quality;
+ if (thrmid > thrmax)
+ thrmid = thrmax;
+
+ thrside = sidemin / quality;
+ if (thrside > sidemax)
+ thrside = sidemax;
+
+ thrmid += 1.0;
+ break;
+ case JOINT_IS:
+ isthr = 0.18 / (quality * quality);
+ if (isthr > isthrmax)
+ isthr = isthrmax;
+
+ isthr += 1.0;
+ break;
+ }
+
+ // convert into energy
+ thrmid *= thrmid;
+ thrside *= thrside;
+ isthr *= isthr;
+
+ for (chn = 0; chn < maxchan; chn++)
+ {
+ int group;
+ int bookcnt = 0;
+ CoderInfo *cp = coder + chn;
+
+ if (!channel[chn].present)
+ continue;
+
+ for (group = 0; group < cp->groups.n; group++)
+ {
+ int band;
+ for (band = 0; band < cp->sfbn; band++)
+ {
+ cp->book[bookcnt] = HCB_NONE;
+ cp->sf[bookcnt] = 0;
+ bookcnt++;
+ }
+ }
+ }
+ for (chn = 0; chn < maxchan; chn++)
+ {
+ int rch;
+ int cnt;
+ int group;
+ int sfcnt = 0;
+ int start = 0;
+
+ if (!channel[chn].present)
+ continue;
+ if (!((channel[chn].cpe) && (channel[chn].ch_is_left)))
+ continue;
+
+ rch = channel[chn].paired_ch;
+
+ channel[chn].common_window = 0;
+ channel[chn].msInfo.is_present = 0;
+ channel[rch].msInfo.is_present = 0;
+
+ if (coder[chn].block_type != coder[rch].block_type)
+ continue;
+ if (coder[chn].groups.n != coder[rch].groups.n)
+ continue;
+
+ channel[chn].common_window = 1;
+ for (cnt = 0; cnt < coder[chn].groups.n; cnt++)
+ if (coder[chn].groups.len[cnt] != coder[rch].groups.len[cnt])
+ {
+ channel[chn].common_window = 0;
+ goto skip;
+ }
+
+ if (mode == JOINT_MS)
+ {
+ channel[chn].common_window = 1;
+ channel[chn].msInfo.is_present = 1;
+ channel[rch].msInfo.is_present = 1;
+ }
+
+ for (group = 0; group < coder->groups.n; group++)
+ {
+ int end = start + coder->groups.len[group];
+ switch(mode) {
+ case JOINT_MS:
+ midside(coder + chn, channel + chn, s[chn], s[rch], &sfcnt,
+ start, end, thrmid, thrside);
+ break;
+ case JOINT_IS:
+ stereo(coder + chn, coder + rch, s[chn], s[rch], &sfcnt, start, end, isthr);
+ break;
+ }
+ start = end;
+ }
+ skip:;
+ }
+}
--- /dev/null
+++ b/libfaac/stereo.h
@@ -1,0 +1,29 @@
+/****************************************************************************
+ Intensity Stereo
+
+ Copyright (C) 2017 Krzysztof Nikiel
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+****************************************************************************/
+
+#include "channels.h"
+#include "util.h"
+
+void AACstereo(CoderInfo *coder,
+ ChannelInfo *channel,
+ double *s[MAX_CHANNELS],
+ int maxchan,
+ double quality,
+ int mode
+ );
--- a/libfaac/version.h
+++ /dev/null
@@ -1,8 +1,0 @@
-#ifndef _VERSION_H_
-#define _VERSION_H_
-
-#define FAAC_RELEASE 1
-
-#define FAAC_VERSION PACKAGE_VERSION
-
-#endif