Skip to content

Commit bfd9004

Browse files
authored
stereo: add Mixed Mode joint stereo; fix midside guard; optimize throughput (#110)
Introduce JOINT_MIXED (mode 3) as the new default joint stereo mode. Per scale-factor band it selects IS above 5.5 kHz, M/S where channels are correlated, or L/R otherwise, recovering stereo image vs. forced IS. Fix a band-silencing bug in midside(): the thrside zeroing ran on already-M/S-coded bands, producing L=R=0 on decode. Add the !ms guard. Guard enrgSum/Diff against negative rounding before sqrt (NaN fix). Keep IS available at low sample rates by capping the frequency floor to 70% of Nyquist. Factor repeated M/S, IS, and channel-zeroing transforms into apply_ms(), apply_is(), and zero_channel() helpers. Single-pass energy accumulation and restrict-qualified pointers reduce per-band work. Expose Mixed Mode in the CLI (--joint 3) and GUI dropdown. Move the Joint Stereo dropdown below the stereo checkboxes in the GUI.
1 parent c5c2494 commit bfd9004

8 files changed

Lines changed: 419 additions & 123 deletions

File tree

frontend/faacgui.rc

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,8 @@ END
5252
// Dialog
5353
//
5454

55-
IDD_MAINDIALOG DIALOGEX 0, 0, 264, 190
56-
STYLE DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION |
55+
IDD_MAINDIALOG DIALOGEX 0, 0, 264, 200
56+
STYLE DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION |
5757
WS_SYSMENU
5858
CAPTION "FAAC GUI"
5959
FONT 8, "MS Sans Serif"
@@ -62,21 +62,21 @@ BEGIN
6262
WS_EX_STATICEDGE
6363
PUSHBUTTON "...",IDC_SELECT_OUTPUTFILE,225,33,19,14,WS_DISABLED,
6464
WS_EX_STATICEDGE
65-
CONTROL "Allow Mid/Side",IDC_ALLOWMIDSIDE,"Button",
66-
BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,14,81,71,10
65+
COMBOBOX IDC_JOINTMODE,14,126,71,60,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
66+
LTEXT "Joint Stereo",IDC_STATIC,14,117,56,8
6767
LTEXT "Quantizer\nquality", IDC_STATIC, 98, 73, 44, 18
6868
EDITTEXT IDC_QUALITY, 138, 76, 30, 12, ES_AUTOHSCROLL
6969
CONTROL "", IDC_STATIC, "static", SS_SUNKEN, 98, 94, 70, 30
7070
CONTROL "Set bandwidth", IDC_BWCTL, "Button", BS_AUTOCHECKBOX
7171
| WS_TABSTOP, 102, 96, 62, 12
7272
EDITTEXT IDC_BANDWIDTH,102,109,34,12,ES_AUTOHSCROLL | WS_DISABLED | WS_TABSTOP
7373
LTEXT "Hz", IDC_STATIC, 140, 111, 10, 8
74-
DEFPUSHBUTTON "Encode",IDOK,200,152,50,14,WS_DISABLED
75-
PUSHBUTTON "Quit",IDCANCEL,200,170,50,14
76-
LTEXT "",IDC_TIME,7,151,190,20
77-
LTEXT "", IDC_COMPILEDATE, 20, 176, 150, 8
74+
DEFPUSHBUTTON "Encode",IDOK,200,162,50,14,WS_DISABLED
75+
PUSHBUTTON "Quit",IDCANCEL,200,180,50,14
76+
LTEXT "",IDC_TIME,7,161,190,20
77+
LTEXT "", IDC_COMPILEDATE, 20, 186, 150, 8
7878
EDITTEXT IDC_INPUTFILENAME,61,12,158,14,ES_AUTOHSCROLL
79-
EDITTEXT IDC_OUTPUTFILENAME,61,33,158,14,ES_AUTOHSCROLL |
79+
EDITTEXT IDC_OUTPUTFILENAME,61,33,158,14,ES_AUTOHSCROLL |
8080
WS_DISABLED
8181
LTEXT "Input File:",IDC_STATIC,18,13,38,8
8282
LTEXT "Output File:",IDC_STATIC,18,34,37,8
@@ -85,20 +85,20 @@ BEGIN
8585
LTEXT "-",IDC_INPUTPARAMS,32,66,55,8
8686
LTEXT "In:",IDC_STATIC,14,66,12,8
8787
CONTROL "Progress1",IDC_PROGRESS,"msctls_progress32",WS_BORDER,7,
88-
135,250,10
89-
GROUPBOX "Output Format",IDC_STATIC,93,62,164,67
90-
CONTROL "Use RAW output",IDC_USERAW,"Button",BS_AUTOCHECKBOX |
91-
BS_LEFTTEXT | WS_TABSTOP,14,103,71,10
92-
CONTROL "Use TNS",IDC_USETNS,"Button",BS_AUTOCHECKBOX |
93-
BS_LEFTTEXT | WS_TABSTOP,14,92,71,10
94-
COMBOBOX IDC_MPEGVERSION,183,82,67,63,CBS_DROPDOWNLIST |
88+
145,250,10
89+
GROUPBOX "Output Format",IDC_STATIC,93,62,164,77
90+
CONTROL "Use RAW output",IDC_USERAW,"Button",BS_AUTOCHECKBOX |
91+
BS_LEFTTEXT | WS_TABSTOP,14,93,71,10
92+
CONTROL "Use TNS",IDC_USETNS,"Button",BS_AUTOCHECKBOX |
93+
BS_LEFTTEXT | WS_TABSTOP,14,82,71,10
94+
COMBOBOX IDC_MPEGVERSION,183,82,67,63,CBS_DROPDOWNLIST |
9595
WS_VSCROLL | WS_TABSTOP
96-
COMBOBOX IDC_OBJECTTYPE,183,109,67,59,CBS_DROPDOWNLIST |
96+
COMBOBOX IDC_OBJECTTYPE,183,109,67,59,CBS_DROPDOWNLIST |
9797
WS_VSCROLL | WS_TABSTOP | WS_DISABLED
9898
LTEXT "MPEG Version",IDC_STATIC,183,73,56,8
9999
LTEXT "AAC Object Type",IDC_STATIC,183,100,56,8
100-
CONTROL "Use LFE channel",IDC_USELFE,"Button",BS_AUTOCHECKBOX |
101-
BS_LEFTTEXT | WS_DISABLED | WS_TABSTOP,14,114,71,10
100+
CONTROL "Use LFE channel",IDC_USELFE,"Button",BS_AUTOCHECKBOX |
101+
BS_LEFTTEXT | WS_DISABLED | WS_TABSTOP,14,104,71,10
102102
END
103103

104104

frontend/main.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ static help_t help_advanced[] = {
190190
{"--joint 0\tDisable joint stereo coding.\n"},
191191
{"--joint 1\tUse Mid/Side coding.\n"},
192192
{"--joint 2\tUse Intensity Stereo coding.\n"},
193+
{"--joint 3\tUse Mixed Mode (dynamic M/S and IS) coding (default).\n"},
193194
{"--pns <0 .. 10>\tPNS level; 0=disabled.\n"},
194195
{"--mpeg-vers X\tForce AAC MPEG version, X can be 2 or 4\n"},
195196
{"--shortctl X\tEnforce block type (0 = both (default); 1 = no short; 2 = no\n"
@@ -1020,6 +1021,9 @@ int main(int argc, char *argv[])
10201021
case JOINT_IS:
10211022
fprintf(stderr, " + IS");
10221023
break;
1024+
case JOINT_MIXED:
1025+
fprintf(stderr, " + Mixed");
1026+
break;
10231027
}
10241028
if (myFormat->pnslevel > 0)
10251029
fprintf(stderr, " + PNS");

frontend/maingui.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,10 @@ static DWORD WINAPI EncodeFile(LPVOID pParam)
153153
/* set encoder configuration */
154154
faacEncConfigurationPtr config = faacEncGetCurrentConfiguration(hEncoder);
155155

156-
config->jointmode = IsDlgButtonChecked(hWnd, IDC_ALLOWMIDSIDE) == BST_CHECKED ? 1 : 0;
156+
{
157+
LRESULT mode = SendMessage(GetDlgItem(hWnd, IDC_JOINTMODE), CB_GETCURSEL, 0, 0);
158+
config->jointmode = (mode == CB_ERR) ? JOINT_MIXED : (unsigned int)mode;
159+
}
157160
config->useTns = IsDlgButtonChecked(hWnd, IDC_USETNS) == BST_CHECKED ? 1 : 0;
158161
config->useLfe = IsDlgButtonChecked(hWnd, IDC_USELFE) == BST_CHECKED ? 1 : 0;
159162
config->outputFormat = IsDlgButtonChecked(hWnd, IDC_USERAW) == BST_CHECKED ? 0 : 1;
@@ -339,7 +342,12 @@ static BOOL WINAPI DialogProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
339342
SendMessage(GetDlgItem(hWnd, IDC_OBJECTTYPE), CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"Low Complexity");
340343
SendMessage(GetDlgItem(hWnd, IDC_OBJECTTYPE), CB_SETCURSEL, 0, 0);
341344

342-
CheckDlgButton(hWnd, IDC_ALLOWMIDSIDE, TRUE);
345+
SendMessage(GetDlgItem(hWnd, IDC_JOINTMODE), CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"None");
346+
SendMessage(GetDlgItem(hWnd, IDC_JOINTMODE), CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"M/S");
347+
SendMessage(GetDlgItem(hWnd, IDC_JOINTMODE), CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"IS");
348+
SendMessage(GetDlgItem(hWnd, IDC_JOINTMODE), CB_ADDSTRING, 0, (LPARAM)(LPCTSTR)"Mixed");
349+
SendMessage(GetDlgItem(hWnd, IDC_JOINTMODE), CB_SETCURSEL, 3, 0);
350+
343351
CheckDlgButton(hWnd, IDC_USELFE, FALSE);
344352
CheckDlgButton(hWnd, IDC_USERAW, FALSE);
345353
CheckDlgButton(hWnd, IDC_USETNS, TRUE);

frontend/resource.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#define IDC_SELECT_OUTPUTFILE 1003
1111
#define IDC_INPUTPARAMS 1004
1212
#define IDC_PROGRESS 1006
13-
#define IDC_ALLOWMIDSIDE 1007
13+
#define IDC_JOINTMODE 1007
1414
#define IDC_TIME 1008
1515
#define IDC_BANDWIDTH 1009
1616
#define IDC_QUALITY 1010

include/faaccfg.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ enum stream_format
5151
ADTS_STREAM = 1,
5252
};
5353

54-
enum {JOINT_NONE = 0, JOINT_MS, JOINT_IS};
54+
enum {JOINT_NONE = 0, JOINT_MS, JOINT_IS, JOINT_MIXED};
5555

5656
#pragma pack(push, 1)
5757
typedef struct faacEncConfiguration

libfaac/frame.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ faacEncHandle FAACAPI faacEncOpen(unsigned long sampleRate,
292292
hEncoder->config.copyright = libCopyright;
293293
hEncoder->config.mpegVersion = MPEG4;
294294
hEncoder->config.aacObjectType = LOW;
295-
hEncoder->config.jointmode = JOINT_IS;
295+
hEncoder->config.jointmode = JOINT_MIXED;
296296
hEncoder->config.pnslevel = 4;
297297
hEncoder->config.useLfe = 1;
298298
hEncoder->config.useTns = 0;
@@ -591,7 +591,7 @@ int FAACAPI faacEncEncode(faacEncHandle hpEncoder,
591591
}
592592

593593
AACstereo(coderInfo, channelInfo, hEncoder->freqBuff, numChannels,
594-
(faac_real)hEncoder->aacquantCfg.quality/DEFQUAL, jointmode);
594+
(faac_real)hEncoder->aacquantCfg.quality/DEFQUAL, jointmode, hEncoder->sampleRate);
595595

596596
for (channel = 0; channel < numChannels; channel++) {
597597
BlocQuant(&coderInfo[channel], hEncoder->freqBuff[channel],

0 commit comments

Comments
 (0)