init

decompiled_code:
unsigned int init()
{
int v0; // eax
int v1; // ebp
speed_t v2; // ebp
tcflag_t v3; // ecx
tcflag_t v4; // esi
tcflag_t v5; // ecx
unsigned int v6; // eax
unsigned int result; // eax
unsigned int v8; // ebp
char *v9; // rax
unsigned int v10; // ebp
char *v11; // rax
int v12; // [rsp+8h] [rbp-60h] BYREF
int v13; // [rsp+Ch] [rbp-5Ch] BYREF
int v14; // [rsp+10h] [rbp-58h] BYREF
int v15; // [rsp+14h] [rbp-54h] BYREF
char *file; // [rsp+18h] [rbp-50h] BYREF
struct termios termios_p; // [rsp+20h] [rbp-48h] BYREF

if ( (unsigned int)validateConfigString(&config, "serial_port", &file, 0xFFFFFFFFLL) == 1 )
return 1;
v0 = open(file, 526594);
interfaceFD = v0;
v1 = v0;
if ( v0 < 0 )
{
v8 = *_errno_location();
v9 = strerror(v8);
syslog(3, "Failed to open serial device %s: %s (%i)", file, v9, v8);
return 1;
}
tcgetattr(v0, &termiosOriginalAttr);
tcgetattr(v1, &termios_p);
validateConfigBool(&config, "serial_parity", &v12, 0LL);
validateConfigBool(&config, "serial_even", &v13, 0LL);
validateConfigBool(&config, "serial_2stop", &v14, 0LL);
if ( (unsigned int)validateConfigInt(&config, "serial_baud", &v15, 0xFFFFFFFFLL, 0LL, 0LL, -1LL) == 1 )
return 1;
if ( v15 == 9600 )
{
v2 = 13;
}
else if ( v15 <= 9600 )
{
if ( v15 == 2400 )
{
v2 = 11;
}
else if ( v15 <= 2400 )
{
if ( v15 == 1200 )
{
v2 = 9;
}
else
{
if ( v15 != 1800 )
goto LABEL_26;
v2 = 10;
}
}
else
{
v2 = 12;
if ( v15 != 4800 )
goto LABEL_26;
}
}
else if ( v15 == 57600 )
{
v2 = 4097;
}
else
{
if ( v15 > 57600 )
{
v2 = 4098;
if ( v15 == 115200 )
goto LABEL_9;
LABEL_26:
syslog(3, "[Error] Entry is invalid [1200|1800|2400|4800|9600|19200|38400|57600|115200]: %i", (unsigned int)v15);
return 1;
}
if ( v15 == 19200 )
{
v2 = 14;
}
else
{
if ( v15 != 38400 )
goto LABEL_26;
v2 = 15;
}
}
LABEL_9:
if ( (unsigned int)validateConfigInt(&config, "serial_bits", &v15, 0xFFFFFFFFLL, 0LL, 0LL, 8LL) == 1 )
return 1;
if ( (unsigned int)(v15 - 5) > 3 )
{
syslog(3, "[Error] Entry is invalid [5|6|7|8]: %i", (unsigned int)v15);
return 1;
}
v3 = termios_p.c_cflag;
v4 = termios_p.c_iflag;
if ( v12 )
{
v4 = termios_p.c_iflag | 0x30;
if ( v13 )
{
BYTE1(v3) = BYTE1(termios_p.c_cflag) & 0xFD;
v5 = v3 | 0x980;
}
else
{
v5 = termios_p.c_cflag | 0xB80;
}
}
else
{
BYTE1(v3) = BYTE1(termios_p.c_cflag) & 0xFE;
v5 = v3 | 0x880;
}
v6 = v5 | 0x40;
if ( !v14 )
v6 = v5 & 0xFFFFFFBF;
termios_p.c_lflag &= 0xFFFFFFE4;
termios_p.c_iflag = v4 & 0xFFFFE23F;
termios_p.c_oflag &= 0xFFFFFFFE;
termios_p.c_cflag = ((16 * v15 - 80) | v6 & 0xFFFFFFCF) & 0x7FFFFFFF;
*(_WORD *)&termios_p.c_cc[5] = 256;
if ( cfsetospeed(&termios_p, v2) < 0 )
{
syslog(3, "Failed to set serial output baud rate");
return 1;
}
if ( cfsetispeed(&termios_p, v2) < 0 )
{
syslog(3, "Failed to set serial input baud rate");
return 1;
}
if ( tcsetattr(interfaceFD, 0, &termios_p) == -1 )
{
v10 = *_errno_location();
v11 = strerror(v10);
syslog(3, "Failed to set attributes for serial device %s: %s (%i)", file, v11, v10);
return 1;
}
result = pthread_mutex_init(&interfaceLock, 0LL);
if ( result )
{
syslog(3, "Failed to create interface mutex: %i", result);
return 1;
}
return result;
}

canonical_decompiled_code:
unsigned int func3()
{
int v0; // eax
int v1; // ebp
speed_t v2; // ebp
tcflag_t v3; // ecx
tcflag_t v4; // esi
tcflag_t v5; // ecx
unsigned int v6; // eax
unsigned int result; // eax
unsigned int v8; // ebp
char *v9; // rax
unsigned int v10; // ebp
char *v11; // rax
int v12; // [rsp+8h] [rbp-60h] BYREF
int v13; // [rsp+Ch] [rbp-5Ch] BYREF
int v14; // [rsp+10h] [rbp-58h] BYREF
int v15; // [rsp+14h] [rbp-54h] BYREF
char *file; // [rsp+18h] [rbp-50h] BYREF
struct termios termios_p; // [rsp+20h] [rbp-48h] BYREF

if ( (unsigned int)validateConfigString(&config, "serial_port", &file, 0xFFFFFFFFLL) == 1 )
return 1;
v0 = open(file, 526594);
interfaceFD = v0;
v1 = v0;
if ( v0 < 0 )
{
v8 = *_errno_location();
v9 = strerror(v8);
syslog(3, "Failed to open serial device %s: %s (%i)", file, v9, v8);
return 1;
}
tcgetattr(v0, &termiosOriginalAttr);
tcgetattr(v1, &termios_p);
validateConfigBool(&config, "serial_parity", &v12, 0LL);
validateConfigBool(&config, "serial_even", &v13, 0LL);
validateConfigBool(&config, "serial_2stop", &v14, 0LL);
if ( (unsigned int)validateConfigInt(&config, "serial_baud", &v15, 0xFFFFFFFFLL, 0LL, 0LL, -1LL) == 1 )
return 1;
if ( v15 == 9600 )
{
v2 = 13;
}
else if ( v15 <= 9600 )
{
if ( v15 == 2400 )
{
v2 = 11;
}
else if ( v15 <= 2400 )
{
if ( v15 == 1200 )
{
v2 = 9;
}
else
{
if ( v15 != 1800 )
goto LABEL_26;
v2 = 10;
}
}
else
{
v2 = 12;
if ( v15 != 4800 )
goto LABEL_26;
}
}
else if ( v15 == 57600 )
{
v2 = 4097;
}
else
{
if ( v15 > 57600 )
{
v2 = 4098;
if ( v15 == 115200 )
goto LABEL_9;
LABEL_26:
syslog(3, "[Error] Entry is invalid [1200|1800|2400|4800|9600|19200|38400|57600|115200]: %i", (unsigned int)v15);
return 1;
}
if ( v15 == 19200 )
{
v2 = 14;
}
else
{
if ( v15 != 38400 )
goto LABEL_26;
v2 = 15;
}
}
LABEL_9:
if ( (unsigned int)validateConfigInt(&config, "serial_bits", &v15, 0xFFFFFFFFLL, 0LL, 0LL, 8LL) == 1 )
return 1;
if ( (unsigned int)(v15 - 5) > 3 )
{
syslog(3, "[Error] Entry is invalid [5|6|7|8]: %i", (unsigned int)v15);
return 1;
}
v3 = termios_p.c_cflag;
v4 = termios_p.c_iflag;
if ( v12 )
{
v4 = termios_p.c_iflag | 0x30;
if ( v13 )
{
BYTE1(v3) = BYTE1(termios_p.c_cflag) & 0xFD;
v5 = v3 | 0x980;
}
else
{
v5 = termios_p.c_cflag | 0xB80;
}
}
else
{
BYTE1(v3) = BYTE1(termios_p.c_cflag) & 0xFE;
v5 = v3 | 0x880;
}
v6 = v5 | 0x40;
if ( !v14 )
v6 = v5 & 0xFFFFFFBF;
termios_p.c_lflag &= 0xFFFFFFE4;
termios_p.c_iflag = v4 & 0xFFFFE23F;
termios_p.c_oflag &= 0xFFFFFFFE;
termios_p.c_cflag = ((16 * v15 - 80) | v6 & 0xFFFFFFCF) & 0x7FFFFFFF;
*(_WORD *)&termios_p.c_cc[5] = 256;
if ( cfsetospeed(&termios_p, v2) < 0 )
{
syslog(3, "Failed to set serial output baud rate");
return 1;
}
if ( cfsetispeed(&termios_p, v2) < 0 )
{
syslog(3, "Failed to set serial input baud rate");
return 1;
}
if ( tcsetattr(interfaceFD, 0, &termios_p) == -1 )
{
v10 = *_errno_location();
v11 = strerror(v10);
syslog(3, "Failed to set attributes for serial device %s: %s (%i)", file, v11, v10);
return 1;
}
result = pthread_mutex_init(&interfaceLock, 0LL);
if ( result )
{
syslog(3, "Failed to create interface mutex: %i", result);
return 1;
}
return result;
}

original_code:
static int init(void) {
    struct termios termiosNewAttr;
    const char *serialDevice;
    speed_t serialSpeed;
    tcflag_t serialBits;
    int serialParity, serialEven, serial2Stop, intSetting, status;
    if(validateConfigString(&config, "serial_port", &serialDevice, -1) == 1)
        return 1;
    interfaceFD = open(serialDevice, 02| 0400 | 04000 | 02000000);
    if(interfaceFD < 0) {
        syslog(3, "Failed to open serial device %s: %s (%i)", serialDevice, strerror((*__errno_location ())), (*__errno_location ()));
        return 1;
    }
    tcgetattr(interfaceFD, &termiosOriginalAttr);
    tcgetattr(interfaceFD, &termiosNewAttr);
    validateConfigBool(&config, "serial_parity", &serialParity, 0);
    validateConfigBool(&config, "serial_even", &serialEven, 0);
    validateConfigBool(&config, "serial_2stop", &serial2Stop, 0);
    if(validateConfigInt(&config, "serial_baud", &intSetting, -1, 0, 0, -1) == 1)
        return 1;
    else
        switch(intSetting) {
            case 1200:
                serialSpeed = 0000011;
                break;
            case 1800:
                serialSpeed = 0000012;
                break;
            case 2400:
                serialSpeed = 0000013;
                break;
            case 4800:
                serialSpeed = 0000014;
                break;
            case 9600:
                serialSpeed = 0000015;
                break;
            case 19200:
                serialSpeed = 0000016;
                break;
            case 38400:
                serialSpeed = 0000017;
                break;
            case 57600:
                serialSpeed = 0010001;
                break;
            case 115200:
                serialSpeed = 0010002;
                break;
            default:
                syslog(3, "[Error] Entry is invalid [1200|1800|2400|4800|9600|19200|38400|57600|115200]: %i", intSetting);
                return 1;
        }
    if(validateConfigInt(&config, "serial_bits", &intSetting, -1, 0, 0, 8) == 1)
        return 1;
    else
        switch(intSetting) {
            case 5:
                serialBits = 0000000;
                break;
            case 6:
                serialBits = 0000020;
                break;
            case 7:
                serialBits = 0000040;
                break;
            case 8:
                serialBits = 0000060;
                break;
            default:
                syslog(3, "[Error] Entry is invalid [5|6|7|8]: %i", intSetting);
                return 1;
        }
    termiosNewAttr.c_cflag |= (0004000 | 0000200);
    if(serialParity == 0)
        termiosNewAttr.c_cflag &= ~0000400;
    else {
        termiosNewAttr.c_cflag |= 0000400;
        termiosNewAttr.c_iflag |= (0000020 | 0000040);
        if(serialEven == 0)
            termiosNewAttr.c_cflag |= 0001000;
        else
            termiosNewAttr.c_cflag &= ~0001000;
    }
    if(serial2Stop == 0)
        termiosNewAttr.c_cflag &= ~0000100;
    else
        termiosNewAttr.c_cflag |= 0000100;
    termiosNewAttr.c_cflag &= ~0000060;
    termiosNewAttr.c_cflag |= serialBits;
    termiosNewAttr.c_lflag &= ~(0000002 | 0000010 | 0000020 | 0000001);
    termiosNewAttr.c_cflag &= ~020000000000;
    termiosNewAttr.c_iflag &= ~(0002000 | 0010000 | 0004000);
    termiosNewAttr.c_iflag &= ~(0000400 | 0000200 | 0000100);
    termiosNewAttr.c_oflag &= ~0000001;
    termiosNewAttr.c_cc[6] = 1;
    termiosNewAttr.c_cc[5] = 0;
    if((cfsetospeed(&termiosNewAttr, serialSpeed)) < 0) {
        syslog(3, "Failed to set serial output baud rate");
        return 1;
    }
    if((cfsetispeed(&termiosNewAttr, serialSpeed)) < 0) {
        syslog(3, "Failed to set serial input baud rate");
        return 1;
    }
    if(tcsetattr(interfaceFD, 0, &termiosNewAttr) == -1) {
        syslog(3, "Failed to set attributes for serial device %s: %s (%i)", serialDevice, strerror((*__errno_location ())), (*__errno_location ()));
        return 1;
    }
    if((status = pthread_mutex_init(&interfaceLock, ((void *)0))) != 0) {
        syslog(3, "Failed to create interface mutex: %i", status);
        return 1;
    }
    return 0;
}

canonical_original_code:
static int init() {
    struct termios termiosNewAttr;
    char *serialDevice;
    unsigned int serialSpeed;
    unsigned int serialBits;
    int serialParity; int serialEven; int serial2Stop; int intSetting; int status;
    if(validateConfigString(&config, "serial_port", &serialDevice, -1) == 1)
        return 1;
    interfaceFD = open(serialDevice, 02| 0400 | 04000 | 02000000);
    if(interfaceFD < 0) {
        syslog(3, "Failed to open serial device %s: %s (%i)", serialDevice, strerror((*__errno_location ())), (*__errno_location ()));
        return 1;
    }
    tcgetattr(interfaceFD, &termiosOriginalAttr);
    tcgetattr(interfaceFD, &termiosNewAttr);
    validateConfigBool(&config, "serial_parity", &serialParity, 0);
    validateConfigBool(&config, "serial_even", &serialEven, 0);
    validateConfigBool(&config, "serial_2stop", &serial2Stop, 0);
    if(validateConfigInt(&config, "serial_baud", &intSetting, -1, 0, 0, -1) == 1)
        return 1;
    else
        switch(intSetting) {
            case 1200:
                serialSpeed = 0000011;
                break;
            case 1800:
                serialSpeed = 0000012;
                break;
            case 2400:
                serialSpeed = 0000013;
                break;
            case 4800:
                serialSpeed = 0000014;
                break;
            case 9600:
                serialSpeed = 0000015;
                break;
            case 19200:
                serialSpeed = 0000016;
                break;
            case 38400:
                serialSpeed = 0000017;
                break;
            case 57600:
                serialSpeed = 0010001;
                break;
            case 115200:
                serialSpeed = 0010002;
                break;
            default:
                syslog(3, "[Error] Entry is invalid [1200|1800|2400|4800|9600|19200|38400|57600|115200]: %i", intSetting);
                return 1;
        }
    if(validateConfigInt(&config, "serial_bits", &intSetting, -1, 0, 0, 8) == 1)
        return 1;
    else
        switch(intSetting) {
            case 5:
                serialBits = 0000000;
                break;
            case 6:
                serialBits = 0000020;
                break;
            case 7:
                serialBits = 0000040;
                break;
            case 8:
                serialBits = 0000060;
                break;
            default:
                syslog(3, "[Error] Entry is invalid [5|6|7|8]: %i", intSetting);
                return 1;
        }
    termiosNewAttr.c_cflag |= (0004000 | 0000200);
    if(serialParity == 0)
        termiosNewAttr.c_cflag &= ~0000400;
    else {
        termiosNewAttr.c_cflag |= 0000400;
        termiosNewAttr.c_iflag |= (0000020 | 0000040);
        if(serialEven == 0)
            termiosNewAttr.c_cflag |= 0001000;
        else
            termiosNewAttr.c_cflag &= ~0001000;
    }
    if(serial2Stop == 0)
        termiosNewAttr.c_cflag &= ~0000100;
    else
        termiosNewAttr.c_cflag |= 0000100;
    termiosNewAttr.c_cflag &= ~0000060;
    termiosNewAttr.c_cflag |= serialBits;
    termiosNewAttr.c_lflag &= ~(0000002 | 0000010 | 0000020 | 0000001);
    termiosNewAttr.c_cflag &= ~020000000000;
    termiosNewAttr.c_iflag &= ~(0002000 | 0010000 | 0004000);
    termiosNewAttr.c_iflag &= ~(0000400 | 0000200 | 0000100);
    termiosNewAttr.c_oflag &= ~0000001;
    termiosNewAttr.c_cc[6] = 1;
    termiosNewAttr.c_cc[5] = 0;
    if((cfsetospeed(&termiosNewAttr, serialSpeed)) < 0) {
        syslog(3, "Failed to set serial output baud rate");
        return 1;
    }
    if((cfsetispeed(&termiosNewAttr, serialSpeed)) < 0) {
        syslog(3, "Failed to set serial input baud rate");
        return 1;
    }
    if(tcsetattr(interfaceFD, 0, &termiosNewAttr) == -1) {
        syslog(3, "Failed to set attributes for serial device %s: %s (%i)", serialDevice, strerror((*__errno_location ())), (*__errno_location ()));
        return 1;
    }
    if((status = pthread_mutex_init(&interfaceLock, ((void *)0))) != 0) {
        syslog(3, "Failed to create interface mutex: %i", status);
        return 1;
    }
    return 0;
}

variable_types: struct termios { unsigned int c_iflag; unsigned int c_oflag; unsigned int c_cflag; unsigned int c_lflag; unsigned char c_line; unsigned char c_cc[32]; unsigned int c_ispeed; unsigned int c_ospeed; }

variable_types:
serialDevice
char *

variable_types:
serialSpeed
unsigned int

variable_types:
serialBits
unsigned int

variable_types: serialParity int

variable_types: serialEven int

variable_types: intSetting int

variable_types: status int


help

repo: therealmuffin/synchronator

decompiled_code:
int help()
{
return puts("Serial");
}

canonical_decompiled_code:
int func4()
{
return puts("Serial");
}

original_code:
static void help(void) {
    printf("Serial\n"
          );
}

canonical_original_code:
static void help() {
    printf("Serial\n"
          );
}

return_type: void


setExternalVolume

decompiled_code:
void __fastcall __noreturn setExternalVolume(void *a1)
{
double v1; // xmm2_8
double v2; // xmm1_8
__int64 v3; // rdx
double v4; // xmm0_8
__int64 v5; // rdi
__int64 v6; // rsi
__int64 v7; // rax
int *v8; // rax
double v9; // [rsp+0h] [rbp-18h] BYREF
__int64 v10; // [rsp+8h] [rbp-10h] BYREF

if ( pthread_sigmask(0, &thread_sigmask, 0LL) < 0 )
{
v8 = _errno_location();
syslog(3, "Failed to ignore signals in smoothVolume: %i", (unsigned int)*v8);
pthread_kill(mainThread, 15);
pause();
}
if ( resetInProgress == 1 )
resetVolume_isra_0();
while ( 1 )
{
v2 = *(double *)&requestedVolume;
if ( *(double *)&actualVolume == *(double *)&requestedVolume )
pthread_exit(0LL);
if ( !*((_DWORD *)&common_data + 1) )
{
if ( *(double *)&actualVolume <= *(double *)&requestedVolume )
{
v4 = *(double *)&actualVolume + 1.0;
v5 = qword_CA8;
v6 = dword_CB4;
}
else
{
v4 = *(double *)&actualVolume - 1.0;
v5 = localSettings;
v6 = dword_CB0;
}
v7 = *((_QWORD *)&common_data + 17);
actualVolume = *(_QWORD *)&v4;
if ( (*(unsigned int (__fastcall **)(__int64, __int64))(v7 + 40))(v5, v6) == 1 )
{
syslog(3, "Failed to send volume command");
pthread_kill(mainThread, 15);
pause();
}
goto LABEL_11;
}
v1 = *(float *)&dword_CC0;
if ( *(double *)&actualVolume <= *(double *)&requestedVolume )
break;
if ( *(double *)&actualVolume - *(double *)&requestedVolume <= v1 )
goto LABEL_20;
v2 = *(double *)&actualVolume - v1;
*(double *)&actualVolume = *(double *)&actualVolume - v1;
LABEL_8:
v3 = *((_QWORD *)&common_data + 18);
if ( !strcmp(*(const char **)(v3 + 24), "log") )
{
v10 = (unsigned int)(int)v2;
(*(void (__fastcall **)(__int64 *, double *))(v3 + 56))(&v10, &v9);
}
else
{
v9 = v2;
}
qword_CB8(&v9);
LABEL_11:
syslog(
7,
"Smooth volume level status: current (requested): %.2f (%.2f)",
*(double *)&actualVolume,
*(double *)&requestedVolume);
clock_nanosleep(1, 0, &req, 0LL);
}
if ( *(double *)&requestedVolume - *(double *)&actualVolume > v1 )
{
v2 = v1 + *(double *)&actualVolume;
*(double *)&actualVolume = v1 + *(double *)&actualVolume;
goto LABEL_8;
}
LABEL_20:
actualVolume = requestedVolume;
goto LABEL_8;
}

canonical_decompiled_code:
void __fastcall __noreturn func5(void *a1)
{
double v1; // xmm2_8
double v2; // xmm1_8
__int64 v3; // rdx
double v4; // xmm0_8
__int64 v5; // rdi
__int64 v6; // rsi
__int64 v7; // rax
int *v8; // rax
double v9; // [rsp+0h] [rbp-18h] BYREF
__int64 v10; // [rsp+8h] [rbp-10h] BYREF

if ( pthread_sigmask(0, &thread_sigmask, 0LL) < 0 )
{
v8 = _errno_location();
syslog(3, "Failed to ignore signals in smoothVolume: %i", (unsigned int)*v8);
pthread_kill(mainThread, 15);
pause();
}
if ( resetInProgress == 1 )
func3();
while ( 1 )
{
v2 = *(double *)&requestedVolume;
if ( *(double *)&actualVolume == *(double *)&requestedVolume )
pthread_exit(0LL);
if ( !*((_DWORD *)&common_data + 1) )
{
if ( *(double *)&actualVolume <= *(double *)&requestedVolume )
{
v4 = *(double *)&actualVolume + 1.0;
v5 = qword_CA8;
v6 = dword_CB4;
}
else
{
v4 = *(double *)&actualVolume - 1.0;
v5 = localSettings;
v6 = dword_CB0;
}
v7 = *((_QWORD *)&common_data + 17);
actualVolume = *(_QWORD *)&v4;
if ( (*(unsigned int (__fastcall **)(__int64, __int64))(v7 + 40))(v5, v6) == 1 )
{
syslog(3, "Failed to send volume command");
pthread_kill(mainThread, 15);
pause();
}
goto LABEL_11;
}
v1 = *(float *)&dword_CC0;
if ( *(double *)&actualVolume <= *(double *)&requestedVolume )
break;
if ( *(double *)&actualVolume - *(double *)&requestedVolume <= v1 )
goto LABEL_20;
v2 = *(double *)&actualVolume - v1;
*(double *)&actualVolume = *(double *)&actualVolume - v1;
LABEL_8:
v3 = *((_QWORD *)&common_data + 18);
if ( !strcmp(*(const char **)(v3 + 24), "log") )
{
v10 = (unsigned int)(int)v2;
(*(void (__fastcall **)(__int64 *, double *))(v3 + 56))(&v10, &v9);
}
else
{
v9 = v2;
}
qword_CB8(&v9);
LABEL_11:
syslog(
7,
"Smooth volume level status: current (requested): %.2f (%.2f)",
*(double *)&actualVolume,
*(double *)&requestedVolume);
clock_nanosleep(1, 0, &req, 0LL);
}
if ( *(double *)&requestedVolume - *(double *)&actualVolume > v1 )
{
v2 = v1 + *(double *)&actualVolume;
*(double *)&actualVolume = v1 + *(double *)&actualVolume;
goto LABEL_8;
}
LABEL_20:
actualVolume = requestedVolume;
goto LABEL_8;
}

original_code:
static void *setExternalVolume(void *unused) {
    double actualExternalVolume;
    if(pthread_sigmask(0, &thread_sigmask, ((void *)0)) < 0) {
        syslog(3, "Failed to ignore signals in smoothVolume: %i", (*__errno_location ()));
        pthread_kill(mainThread, 15);
        pause();
    }
    if(resetInProgress == 1)
        resetVolume();
    while(actualVolume != requestedVolume) {
        if(common_data.discrete_volume) {
            if(actualVolume > requestedVolume) {
                if((actualVolume - requestedVolume) > localSettings.volumeMutation) {
                    actualVolume -= localSettings.volumeMutation;
                }
                else {
                    actualVolume = requestedVolume;
                }
            }
            else {
                if((requestedVolume - actualVolume) > localSettings.volumeMutation) {
                    actualVolume += localSettings.volumeMutation;
                }
                else {
                    actualVolume = requestedVolume;
                }
            }
            if(strcmp(common_data.volume->curve, "log") == 0) {
                long x = (long)actualVolume;
                common_data.volume->convertInternal2External(&x, &actualExternalVolume);
            }
            else
                actualExternalVolume = actualVolume;
            localSettings.setDescreteVolume(&actualExternalVolume);
        }
        else {
            char *volCurrent;
            int volLenCurrent = 0;
            if(actualVolume > requestedVolume) {
                volCurrent = localSettings.volMin;
                volLenCurrent = localSettings.volMinLen;
                actualVolume--;
            }
            else {
                volCurrent = localSettings.volPlus;
                volLenCurrent = localSettings.volPlusLen;
                actualVolume++;
            }
            if(common_data.interface->send(volCurrent, volLenCurrent) == 1) {
                syslog(3, "Failed to send volume command");
                pthread_kill(mainThread, 15);
                pause();
            }
        }
        syslog(7, "Smooth volume level status: current (requested): %.2f (%.2f)", actualVolume, requestedVolume);
        clock_nanosleep(1, 0, &localSettings.timeout, ((void *)0));
    }
    pthread_exit(((void *)0));
}

variable_types:
unused
void *

variable_types: actualExternalVolume double

variable_types: x long

variable_types:
volCurrent
char *

variable_types: volLenCurrent int

return_type: void *


deinit

decompiled_code:
int deinit()
{
pthread_t v0; // rbp
int v2; // ebx
int *v3; // rbp
int v4; // eax
char *v5; // rax
char *v6; // rax

v0 = setExternalVolumeThread;
if ( pthread_equal(setExternalVolumeThread, thisThread) )
return pthread_attr_destroy(&thread_attr);
v2 = pthread_kill(v0, 0);
v3 = _errno_location();
if ( !v2 && pthread_cancel(setExternalVolumeThread) )
{
v5 = strerror(*v3);
syslog(4, "Unable request cancelation for smoothVolume thread: %s", v5);
}
v4 = pthread_join(setExternalVolumeThread, 0LL);
*v3 = v4;
if ( v4 )
{
v6 = strerror(v4);
syslog(4, "Unable to join smoothVolume thread: %s\n", v6);
}
setExternalVolumeThread = thisThread;
return pthread_attr_destroy(&thread_attr);
}

canonical_decompiled_code:
int func0()
{
pthread_t v0; // rbp
int v2; // ebx
int *v3; // rbp
int v4; // eax
char *v5; // rax
char *v6; // rax

v0 = setExternalVolumeThread;
if ( pthread_equal(setExternalVolumeThread, thisThread) )
return pthread_attr_destroy(&thread_attr);
v2 = pthread_kill(v0, 0);
v3 = _errno_location();
if ( !v2 && pthread_cancel(setExternalVolumeThread) )
{
v5 = strerror(*v3);
syslog(4, "Unable request cancelation for smoothVolume thread: %s", v5);
}
v4 = pthread_join(setExternalVolumeThread, 0LL);
*v3 = v4;
if ( v4 )
{
v6 = strerror(v4);
syslog(4, "Unable to join smoothVolume thread: %s\n", v6);
}
setExternalVolumeThread = thisThread;
return pthread_attr_destroy(&thread_attr);
}

original_code:
static void deinit(void) {
    if(!pthread_equal(setExternalVolumeThread, thisThread)) {
        if(pthread_kill(setExternalVolumeThread, 0) == 0 && pthread_cancel(setExternalVolumeThread) != 0)
            syslog(4, "Unable request cancelation for smoothVolume thread: %s", strerror((*__errno_location ())));
        if(((*__errno_location ()) = pthread_join(setExternalVolumeThread, ((void *)0))) != 0)
            syslog(4, "Unable to join smoothVolume thread: %s\n", strerror((*__errno_location ())));
        setExternalVolumeThread = thisThread;
    }
    pthread_attr_destroy(&thread_attr);
}

canonical_original_code:
static void deinit() {
    if(!pthread_equal(setExternalVolumeThread, thisThread)) {
        if(pthread_kill(setExternalVolumeThread, 0) == 0 && pthread_cancel(setExternalVolumeThread) != 0)
            syslog(4, "Unable request cancelation for smoothVolume thread: %s", strerror((*__errno_location ())));
        if(((*__errno_location ()) = pthread_join(setExternalVolumeThread, ((void *)0))) != 0)
            syslog(4, "Unable to join smoothVolume thread: %s\n", strerror((*__errno_location ())));
        setExternalVolumeThread = thisThread;
    }
    pthread_attr_destroy(&thread_attr);
}


process

decompiled_code:
__int64 __fastcall process(_QWORD *a1)
{
__int64 v1; // rdx
int v2; // ebp
pthread_t v3; // r12
pthread_t v4; // r13
unsigned int v5; // er12
__int64 v7; // rdx
pthread_t v8; // rbp
int *v9; // rbx
int v10; // eax
char *v11; // rax
__int64 v12[6]; // [rsp+0h] [rbp-30h] BYREF

if ( resetInProgress )
return 0LL;
if ( !*((_DWORD *)&common_data + 1) && !*a1 )
{
clock_gettime(1, &timestampCurrent);
if ( dword_CC8 && timestampCurrent.tv_sec - (__int64)timestampLastMute > dword_CC8 )
{
timestampLastMute = (__int128)_mm_load_si128((const __m128i *)&timestampCurrent);
}
else
{
syslog(7, "Initiating volume reset");
resetInProgress = 1;
pthread_cancel(setExternalVolumeThread);
}
}
v1 = *((_QWORD *)&common_data + 18);
if ( strcmp(*(const char **)(v1 + 24), "log") )
{
(*(void (__fastcall **)(_QWORD *, __int64 *))(v1 + 56))(a1, &requestedVolume);
v2 = *((_DWORD *)&common_data + 1);
if ( !v2 )
goto LABEL_6;
LABEL_10:
v3 = thisThread;
v4 = setExternalVolumeThread;
if ( pthread_equal(setExternalVolumeThread, thisThread) )
{
if ( v2 != 1 )
goto LABEL_7;
LABEL_12:
v7 = *((_QWORD *)&common_data + 18);
if ( !strcmp(*(const char **)(v7 + 24), "log") )
{
(*(void (__fastcall **)(_QWORD, __int64 *))(v7 + 64))((unsigned int)((_DWORD)&common_data + 64), v12);
v3 = thisThread;
*(double *)&actualVolume = (double)SLODWORD(v12[0]);
}
else
{
actualVolume = *((_QWORD *)&common_data + 8);
}
LABEL_17:
v8 = setExternalVolumeThread;
if ( !pthread_equal(setExternalVolumeThread, v3) )
{
v9 = _errno_location();
v10 = pthread_join(v8, 0LL);
*v9 = v10;
if ( v10 )
{
v11 = strerror(v10);
syslog(4, "Unable to join smoothVolume thread: %s\n", v11);
}
}
goto LABEL_7;
}
LABEL_15:
if ( !(resetInProgress | pthread_kill(v4, 0)) )
return 0LL;
if ( *((_DWORD *)&common_data + 1) != 1 )
goto LABEL_17;
goto LABEL_12;
}
v2 = *((_DWORD *)&common_data + 1);
*(double *)&requestedVolume = (double)(int)*a1;
if ( v2 )
goto LABEL_10;
LABEL_6:
v3 = thisThread;
v4 = setExternalVolumeThread;
*(double *)&requestedVolume = (double)(int)*(double *)&requestedVolume;
if ( !pthread_equal(setExternalVolumeThread, thisThread) )
goto LABEL_15;
LABEL_7:
v5 = pthread_create(&setExternalVolumeThread, &thread_attr, setExternalVolume, 0LL);
if ( !v5 )
return 0LL;
pthread_attr_destroy(&thread_attr);
syslog(3, "Failed to open smoothVolume thread: %i", v5);
pthread_kill(mainThread, 15);
pause();
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func1(_QWORD *a1)
{
__int64 v1; // rdx
int v2; // ebp
pthread_t v3; // r12
pthread_t v4; // r13
unsigned int v5; // er12
__int64 v7; // rdx
pthread_t v8; // rbp
int *v9; // rbx
int v10; // eax
char *v11; // rax
__int64 v12[6]; // [rsp+0h] [rbp-30h] BYREF

if ( resetInProgress )
return 0LL;
if ( !*((_DWORD *)&common_data + 1) && !*a1 )
{
clock_gettime(1, &timestampCurrent);
if ( dword_CC8 && timestampCurrent.tv_sec - (__int64)timestampLastMute > dword_CC8 )
{
timestampLastMute = (__int128)_mm_load_si128((const __m128i *)&timestampCurrent);
}
else
{
syslog(7, "Initiating volume reset");
resetInProgress = 1;
pthread_cancel(setExternalVolumeThread);
}
}
v1 = *((_QWORD *)&common_data + 18);
if ( strcmp(*(const char **)(v1 + 24), "log") )
{
(*(void (__fastcall **)(_QWORD *, __int64 *))(v1 + 56))(a1, &requestedVolume);
v2 = *((_DWORD *)&common_data + 1);
if ( !v2 )
goto LABEL_6;
LABEL_10:
v3 = thisThread;
v4 = setExternalVolumeThread;
if ( pthread_equal(setExternalVolumeThread, thisThread) )
{
if ( v2 != 1 )
goto LABEL_7;
LABEL_12:
v7 = *((_QWORD *)&common_data + 18);
if ( !strcmp(*(const char **)(v7 + 24), "log") )
{
(*(void (__fastcall **)(_QWORD, __int64 *))(v7 + 64))((unsigned int)((_DWORD)&common_data + 64), v12);
v3 = thisThread;
*(double *)&actualVolume = (double)SLODWORD(v12[0]);
}
else
{
actualVolume = *((_QWORD *)&common_data + 8);
}
LABEL_17:
v8 = setExternalVolumeThread;
if ( !pthread_equal(setExternalVolumeThread, v3) )
{
v9 = _errno_location();
v10 = pthread_join(v8, 0LL);
*v9 = v10;
if ( v10 )
{
v11 = strerror(v10);
syslog(4, "Unable to join smoothVolume thread: %s\n", v11);
}
}
goto LABEL_7;
}
LABEL_15:
if ( !(resetInProgress | pthread_kill(v4, 0)) )
return 0LL;
if ( *((_DWORD *)&common_data + 1) != 1 )
goto LABEL_17;
goto LABEL_12;
}
v2 = *((_DWORD *)&common_data + 1);
*(double *)&requestedVolume = (double)(int)*a1;
if ( v2 )
goto LABEL_10;
LABEL_6:
v3 = thisThread;
v4 = setExternalVolumeThread;
*(double *)&requestedVolume = (double)(int)*(double *)&requestedVolume;
if ( !pthread_equal(setExternalVolumeThread, thisThread) )
goto LABEL_15;
LABEL_7:
v5 = pthread_create(&setExternalVolumeThread, &thread_attr, setExternalVolume, 0LL);
if ( !v5 )
return 0LL;
pthread_attr_destroy(&thread_attr);
syslog(3, "Failed to open smoothVolume thread: %i", v5);
pthread_kill(mainThread, 15);
pause();
return 0LL;
}

original_code:
static int process(long *volumeInternal) {
    int status;
    if(resetInProgress)
        return 0;
    if(!common_data.discrete_volume && *volumeInternal == 0) {
        clock_gettime(1 , &timestampCurrent);
        if(!localSettings.resetInterval || (timestampCurrent.tv_sec - timestampLastMute.tv_sec) <= localSettings.resetInterval) {
            syslog(7, "Initiating volume reset");
            resetInProgress = 1;
            pthread_cancel(setExternalVolumeThread);
        }
        else
            timestampLastMute = timestampCurrent;
    }
    if(strcmp(common_data.volume->curve, "log") == 0) {
        requestedVolume = *volumeInternal;
    }
    else {
        common_data.volume->convertInternal2External(volumeInternal, &requestedVolume);
    }
    if(common_data.discrete_volume == 0) {
        requestedVolume = (int)requestedVolume;
    }
    if(!pthread_equal(setExternalVolumeThread, thisThread) &&
    pthread_kill(setExternalVolumeThread, 0) == 0 && !resetInProgress)
        return 0;
    if(common_data.discrete_volume == 1) {
        if(strcmp(common_data.volume->curve, "log") == 0) {
            long actualInternalVolume;
            common_data.volume->convertExternal2Internal(&common_data.volume_level_status, &actualInternalVolume);
            actualVolume = (double)actualInternalVolume;
        }
        else
            actualVolume = common_data.volume_level_status;
    }
    if(!pthread_equal(setExternalVolumeThread, thisThread) &&
    ((*__errno_location ()) = pthread_join(setExternalVolumeThread, ((void *)0))) != 0)
        syslog(4, "Unable to join smoothVolume thread: %s\n", strerror((*__errno_location ())));
    if(status = pthread_create(&setExternalVolumeThread, &thread_attr, setExternalVolume, ((void *)0))) {
        pthread_attr_destroy(&thread_attr);
        syslog(3, "Failed to open smoothVolume thread: %i", status);
        pthread_kill(mainThread, 15);
        pause();
    }
    return 0;
}

variable_types:
volumeInternal
long *

variable_types: actualInternalVolume long

return_type: int


reinit

decompiled_code:
__int64 reinit()
{
int v1; // eax
double v2; // xmm0_8
__int64 v3; // rax
pthread_t v4; // rbp
pthread_t v5; // r12
unsigned int v6; // er12
pthread_t v7; // r12
int *v8; // rbp
int v9; // eax
char *v10; // rax

if ( resetInProgress )
return 0LL;
resetInProgress = 1;
reinitInProgress = 1;
pthread_cancel(setExternalVolumeThread);
syslog(7, "Initiating volume reinitialisation");
v1 = *((_DWORD *)&common_data + 42);
if ( v1 >= *((_DWORD *)&common_data + 8) )
{
v2 = (double)v1;
v3 = *((_QWORD *)&common_data + 18);
defaultVolume = *(_QWORD *)&v2;
(*(void (__fastcall **)(__int64 *))(v3 + 40))(&defaultVolume);
}
v4 = thisThread;
v5 = setExternalVolumeThread;
if ( !pthread_equal(setExternalVolumeThread, thisThread) )
{
if ( !(resetInProgress | pthread_kill(v5, 0)) )
return 0LL;
v7 = setExternalVolumeThread;
if ( !pthread_equal(setExternalVolumeThread, v4) )
{
v8 = _errno_location();
v9 = pthread_join(v7, 0LL);
*v8 = v9;
if ( v9 )
{
v10 = strerror(v9);
syslog(4, "Unable to join smoothVolume thread: %s\n", v10);
}
}
}
v6 = pthread_create(&setExternalVolumeThread, &thread_attr, setExternalVolume, 0LL);
if ( !v6 )
return 0LL;
pthread_attr_destroy(&thread_attr);
syslog(3, "Failed to open smoothVolume thread: %i", v6);
pthread_kill(mainThread, 15);
pause();
return 0LL;
}

canonical_decompiled_code:
__int64 func2()
{
int v1; // eax
double v2; // xmm0_8
__int64 v3; // rax
pthread_t v4; // rbp
pthread_t v5; // r12
unsigned int v6; // er12
pthread_t v7; // r12
int *v8; // rbp
int v9; // eax
char *v10; // rax

if ( resetInProgress )
return 0LL;
resetInProgress = 1;
reinitInProgress = 1;
pthread_cancel(setExternalVolumeThread);
syslog(7, "Initiating volume reinitialisation");
v1 = *((_DWORD *)&common_data + 42);
if ( v1 >= *((_DWORD *)&common_data + 8) )
{
v2 = (double)v1;
v3 = *((_QWORD *)&common_data + 18);
defaultVolume = *(_QWORD *)&v2;
(*(void (__fastcall **)(__int64 *))(v3 + 40))(&defaultVolume);
}
v4 = thisThread;
v5 = setExternalVolumeThread;
if ( !pthread_equal(setExternalVolumeThread, thisThread) )
{
if ( !(resetInProgress | pthread_kill(v5, 0)) )
return 0LL;
v7 = setExternalVolumeThread;
if ( !pthread_equal(setExternalVolumeThread, v4) )
{
v8 = _errno_location();
v9 = pthread_join(v7, 0LL);
*v8 = v9;
if ( v9 )
{
v10 = strerror(v9);
syslog(4, "Unable to join smoothVolume thread: %s\n", v10);
}
}
}
v6 = pthread_create(&setExternalVolumeThread, &thread_attr, setExternalVolume, 0LL);
if ( !v6 )
return 0LL;
pthread_attr_destroy(&thread_attr);
syslog(3, "Failed to open smoothVolume thread: %i", v6);
pthread_kill(mainThread, 15);
pause();
return 0LL;
}

original_code:
static int reinit(void) {
    if(resetInProgress)
        return 0;
    reinitInProgress = resetInProgress = 1;
    pthread_cancel(setExternalVolumeThread);
    syslog(7, "Initiating volume reinitialisation");
    int status;
    if(common_data.defaultExternalVolume >= common_data.initial_volume_min) {
        defaultVolume = common_data.defaultExternalVolume;
        common_data.volume->convertExternal2Mixer(&defaultVolume);
    }
    if(!pthread_equal(setExternalVolumeThread, thisThread) &&
    pthread_kill(setExternalVolumeThread, 0) == 0 && !resetInProgress)
        return 0;
    if(!pthread_equal(setExternalVolumeThread, thisThread) &&
    ((*__errno_location ()) = pthread_join(setExternalVolumeThread, ((void *)0))) != 0)
        syslog(4, "Unable to join smoothVolume thread: %s\n", strerror((*__errno_location ())));
    if(status = pthread_create(&setExternalVolumeThread, &thread_attr, setExternalVolume, ((void *)0))) {
        pthread_attr_destroy(&thread_attr);
        syslog(3, "Failed to open smoothVolume thread: %i", status);
        pthread_kill(mainThread, 15);
        pause();
    }
    return 0;
}

canonical_original_code:
static int reinit() {
    if(resetInProgress)
        return 0;
    reinitInProgress = resetInProgress = 1;
    pthread_cancel(setExternalVolumeThread);
    syslog(7, "Initiating volume reinitialisation");
    int status;
    if(common_data.defaultExternalVolume >= common_data.initial_volume_min) {
        defaultVolume = common_data.defaultExternalVolume;
        common_data.volume->convertExternal2Mixer(&defaultVolume);
    }
    if(!pthread_equal(setExternalVolumeThread, thisThread) &&
    pthread_kill(setExternalVolumeThread, 0) == 0 && !resetInProgress)
        return 0;
    if(!pthread_equal(setExternalVolumeThread, thisThread) &&
    ((*__errno_location ()) = pthread_join(setExternalVolumeThread, ((void *)0))) != 0)
        syslog(4, "Unable to join smoothVolume thread: %s\n", strerror((*__errno_location ())));
    if(status = pthread_create(&setExternalVolumeThread, &thread_attr, setExternalVolume, ((void *)0))) {
        pthread_attr_destroy(&thread_attr);
        syslog(3, "Failed to open smoothVolume thread: %i", status);
        pthread_kill(mainThread, 15);
        pause();
    }
    return 0;
}


init

decompiled_code:
__int64 __fastcall init(__int64 a1, const char *a2, const char *a3)
{
int v4; // eax
unsigned int v5; // eax
__int64 v6; // r12
pthread_t v7; // rax
int v8; // er8
float v9; // xmm0_4
float v10; // xmm0_4
__int64 result; // rax
__int64 v12; // [rsp+0h] [rbp-48h]
__int64 v13; // [rsp+0h] [rbp-48h]
int v14; // [rsp+18h] [rbp-30h] BYREF
int v15[11]; // [rsp+1Ch] [rbp-2Ch] BYREF

v4 = 1000000 * *((_DWORD *)&common_data + 18);
timestampLastMute = 0uLL;
reinitInProgress = 0;
resetInProgress = 0;
req.tv_sec = 0LL;
req.tv_nsec = v4;
sigemptyset(&thread_sigmask);
sigaddset(&thread_sigmask, 2);
sigaddset(&thread_sigmask, 15);
v5 = pthread_attr_init(&thread_attr);
LODWORD(v6) = v5;
if ( v5 )
{
syslog(3, "Failed to initialize thread attributes: %i", v5);
result = 1LL;
}
else
{
pthread_attr_setdetachstate(&thread_attr, 0);
v7 = pthread_self();
v8 = *((_DWORD *)&common_data + 1);
thisThread = v7;
setExternalVolumeThread = v7;
if ( !v8 )
{
localSettings = (__int64)a2;
*((_QWORD *)&common_data + 20) = reinit;
qword_CA8 = (__int64)a3;
dword_CB0 = strlen(a2);
dword_CB4 = strlen(a3);
validateConfigInt(&config, "volume.range", &dword_CC4, 0xFFFFFFFFLL, 1LL, 1000LL, -1LL);
LODWORD(v12) = 2;
validateConfigInt(&config, "volume.double_zero_interval", &dword_CC8, 0xFFFFFFFFLL, 0LL, 30LL, v12);
resetVolume_isra_0();
LODWORD(v13) = dword_CC4;
return (unsigned int)validateConfigInt(
&config,
"volume.max",
(unsigned int)((_DWORD)&common_data + 28),
0xFFFFFFFFLL,
1LL,
(unsigned int)dword_CC4,
v13) == 1;
}
v14 = 0;
qword_CB8 = a1;
validateConfigInt(&config, "volume.mutation", v15, 0xFFFFFFFFLL, 1LL, 1000LL, 100LL);
if ( !strcmp(*(const char **)(*((_QWORD *)&common_data + 16) + 8LL), "ascii") )
config_lookup_int(&config, "volume.precision", &v14);
v9 = (float)(v15[0] / 100);
*(float *)&dword_CC0 = v9;
if ( !v14 || !strcmp(*(const char **)(*((_QWORD *)&common_data + 18) + 24LL), "log") )
{
v10 = (float)(int)v9;
if ( v10 == 0.0 )
{
dword_CC0 = 1065353216;
return (unsigned int)v6;
}
}
else
{
if ( v14 != 1 )
return (unsigned int)v6;
v10 = (float)((int)(float)(v9 * 10.0) / 10);
if ( v10 == 0.0 )
{
dword_CC0 = 1036831949;
return (unsigned int)v6;
}
}
dword_CC0 = LODWORD(v10);
result = (unsigned int)v6;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func4(__int64 a1, const char *a2, const char *a3)
{
int v4; // eax
unsigned int v5; // eax
__int64 v6; // r12
pthread_t v7; // rax
int v8; // er8
float v9; // xmm0_4
float v10; // xmm0_4
__int64 result; // rax
__int64 v12; // [rsp+0h] [rbp-48h]
__int64 v13; // [rsp+0h] [rbp-48h]
int v14; // [rsp+18h] [rbp-30h] BYREF
int v15[11]; // [rsp+1Ch] [rbp-2Ch] BYREF

v4 = 1000000 * *((_DWORD *)&common_data + 18);
timestampLastMute = 0uLL;
reinitInProgress = 0;
resetInProgress = 0;
req.tv_sec = 0LL;
req.tv_nsec = v4;
sigemptyset(&thread_sigmask);
sigaddset(&thread_sigmask, 2);
sigaddset(&thread_sigmask, 15);
v5 = pthread_attr_init(&thread_attr);
LODWORD(v6) = v5;
if ( v5 )
{
syslog(3, "Failed to initialize thread attributes: %i", v5);
result = 1LL;
}
else
{
pthread_attr_setdetachstate(&thread_attr, 0);
v7 = pthread_self();
v8 = *((_DWORD *)&common_data + 1);
thisThread = v7;
setExternalVolumeThread = v7;
if ( !v8 )
{
localSettings = (__int64)a2;
*((_QWORD *)&common_data + 20) = reinit;
qword_CA8 = (__int64)a3;
dword_CB0 = strlen(a2);
dword_CB4 = strlen(a3);
validateConfigInt(&config, "volume.range", &dword_CC4, 0xFFFFFFFFLL, 1LL, 1000LL, -1LL);
LODWORD(v12) = 2;
validateConfigInt(&config, "volume.double_zero_interval", &dword_CC8, 0xFFFFFFFFLL, 0LL, 30LL, v12);
func3();
LODWORD(v13) = dword_CC4;
return (unsigned int)validateConfigInt(
&config,
"volume.max",
(unsigned int)((_DWORD)&common_data + 28),
0xFFFFFFFFLL,
1LL,
(unsigned int)dword_CC4,
v13) == 1;
}
v14 = 0;
qword_CB8 = a1;
validateConfigInt(&config, "volume.mutation", v15, 0xFFFFFFFFLL, 1LL, 1000LL, 100LL);
if ( !strcmp(*(const char **)(*((_QWORD *)&common_data + 16) + 8LL), "ascii") )
config_lookup_int(&config, "volume.precision", &v14);
v9 = (float)(v15[0] / 100);
*(float *)&dword_CC0 = v9;
if ( !v14 || !strcmp(*(const char **)(*((_QWORD *)&common_data + 18) + 24LL), "log") )
{
v10 = (float)(int)v9;
if ( v10 == 0.0 )
{
dword_CC0 = 1065353216;
return (unsigned int)v6;
}
}
else
{
if ( v14 != 1 )
return (unsigned int)v6;
v10 = (float)((int)(float)(v9 * 10.0) / 10);
if ( v10 == 0.0 )
{
dword_CC0 = 1036831949;
return (unsigned int)v6;
}
}
dword_CC0 = LODWORD(v10);
result = (unsigned int)v6;
}
return result;
}

original_code:
static int init(int (*setDescreteVolume)(double *externalVolume), char *volMin, char *volPlus) {
    timestampLastMute = (struct timespec) { 0, 0 };
    resetInProgress = reinitInProgress = 0;
    localSettings.timeout.tv_sec = 0;
    localSettings.timeout.tv_nsec = common_data.volume_timeout*1000000;
    sigemptyset(&thread_sigmask);
    sigaddset(&thread_sigmask, 2);
    sigaddset(&thread_sigmask, 15);
    int tempInt = -1;
    if((tempInt = pthread_attr_init(&thread_attr)) != 0) {
        syslog(3, "Failed to initialize thread attributes: %i", tempInt);
        return 1;
    }
    pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);
    setExternalVolumeThread = thisThread = pthread_self();
    if(common_data.discrete_volume) {
        localSettings.setDescreteVolume = setDescreteVolume;
        int precision = 0;
        int tempInt;
        validateConfigInt(&config, "volume.mutation", &tempInt, -1, 1, 1000, 100);
        if(strcmp(common_data.process->name, "ascii") == 0) {
            config_lookup_int(&config, "volume.precision", &precision);
        }
        localSettings.volumeMutation = (tempInt / 100);
        if(precision == 0 || strcmp(common_data.volume->curve, "log") == 0) {
            localSettings.volumeMutation = (int)localSettings.volumeMutation;
            if(localSettings.volumeMutation == 0) localSettings.volumeMutation = 1;
        }
        else if(precision == 1) {
            localSettings.volumeMutation = (int)(10*localSettings.volumeMutation)/10;
            if(localSettings.volumeMutation == 0) localSettings.volumeMutation = 0.1;
        }
    }
    else {
        common_data.reinitVolume = &reinit;
        localSettings.volMin = volMin;
        localSettings.volPlus = volPlus;
        localSettings.volMinLen = strlen(localSettings.volMin);
        localSettings.volPlusLen = strlen(localSettings.volPlus);
        validateConfigInt(&config, "volume.range", &localSettings.volumeMutationRange, -1, 1, 1000, -1);
        validateConfigInt(&config, "volume.double_zero_interval", &localSettings.resetInterval, -1, 0, 30, 2);
        resetVolume();
        if(validateConfigInt(&config, "volume.max", &common_data.volume_max, -1, 1,
        localSettings.volumeMutationRange, localSettings.volumeMutationRange) == 1)
            return 1;
    }
    return 0;
}

variable_types:
setDescreteVolume
int (*)(double *externalVolume)

variable_types:
volMin
char *

variable_types:
volPlus
char *

variable_types: tempInt int

variable_types: precision int

user_defined_types: struct timespec { long tv_sec; long tv_nsec; }


deinitStatus

decompiled_code:
void deinitStatus()
{
const char **v0; // rbx
const char **v1; // rbp

v0 = (const char **)statusRoot;
if ( statusRoot )
{
do
{
v1 = v0;
v0 = (const char **)v0[2];
syslog(7, "Deleted status: %s", *v1);
free(v1);
}
while ( v0 );
}
}

canonical_decompiled_code:
void func0()
{
const char **v0; // rbx
const char **v1; // rbp

v0 = (const char **)statusRoot;
if ( statusRoot )
{
do
{
v1 = v0;
v0 = (const char **)v0[2];
syslog(7, "Deleted status: %s", *v1);
free(v1);
}
while ( v0 );
}
}

original_code:
static void deinitStatus(void) {
    status_t *statusCurrent = statusRoot;
    status_t *statusBackup;
    while(statusCurrent != ((void *)0)) {
        statusBackup = statusCurrent->nextStatus;
        syslog(7, "Deleted status: %s", statusCurrent->name);
        free(statusCurrent);
        statusCurrent = statusBackup;
    }
}

canonical_original_code:
static void deinitStatus() {
    struct status_t *statusCurrent = statusRoot;
    struct status_t *statusBackup;
    while(statusCurrent != ((void *)0)) {
        statusBackup = statusCurrent->nextStatus;
        syslog(7, "Deleted status: %s", statusCurrent->name);
        free(statusCurrent);
        statusCurrent = statusBackup;
    }
}

variable_types: struct status_t { char *name; char *value; struct status_t *nextStatus; } *


processStatus

decompiled_code:
__int64 __fastcall processStatus(char *s1, const char *a2)
{
const char *v3; // [rsp+8h] [rbp-20h] BYREF

if ( !strcmp(s1, "power") && !strcmp(a2, "deviceon") )
{
retrieveStatus(s1, &v3);
if ( v3 != a2 )
{
sleep(1u);
common_data[20]();
}
}
updateStatus_isra_0(s1, a2);
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func3(char *s1, const char *a2)
{
const char *v3; // [rsp+8h] [rbp-20h] BYREF

if ( !strcmp(s1, "power") && !strcmp(a2, "deviceon") )
{
func1(s1, &v3);
if ( v3 != a2 )
{
sleep(1u);
common_data[20]();
}
}
func2(s1, a2);
return 0LL;
}

original_code:
static int processStatus(const char *name, const char *value) {
    const char *storedValue;
    if(strcmp(name, "power") == 0 && strcmp(value, "deviceon") == 0) {
        retrieveStatus(name, &storedValue);
        if(storedValue != value) {
            sleep(1);
            common_data.reinitVolume();
        }
    }
    updateStatus(name, value);
    return 0;
}

canonical_original_code:
static int processStatus(char *name, char *value) {
    char *storedValue;
    if(strcmp(name, "power") == 0 && strcmp(value, "deviceon") == 0) {
        retrieveStatus(name, &storedValue);
        if(storedValue != value) {
            sleep(1);
            common_data.reinitVolume();
        }
    }
    updateStatus(name, value);
    return 0;
}

variable_types:
name
char *

variable_types:
value
char *

variable_types:
storedValue
char *


getProcessMethod

decompiled_code:
const char **__fastcall getProcessMethod(const char **a1)
{
const char **v1; // r12
const char *v2; // rbp
void **v3; // rbx

v1 = (const char **)processMethods;
v2 = *a1;
if ( *a1 )
{
if ( !processMethods )
return 0LL;
}
else
{
v2 = (const char *)*((_QWORD *)processMethods + 1);
*a1 = v2;
}
v3 = &processMethods;
while ( strcasecmp(v2, v1[1]) )
{
v1 = (const char **)v3[1];
++v3;
if ( !v1 )
return 0LL;
}
return v1;
}

canonical_decompiled_code:
const char **__fastcall func4(const char **a1)
{
const char **v1; // r12
const char *v2; // rbp
void **v3; // rbx

v1 = (const char **)processMethods;
v2 = *a1;
if ( *a1 )
{
if ( !processMethods )
return 0LL;
}
else
{
v2 = (const char *)*((_QWORD *)processMethods + 1);
*a1 = v2;
}
v3 = &processMethods;
while ( strcasecmp(v2, v1[1]) )
{
v1 = (const char **)v3[1];
++v3;
if ( !v1 )
return 0LL;
}
return v1;
}

original_code:
process_method_t *getProcessMethod(const char **name) {
    process_method_t **process_type;
    if (!*name)
        *name = processMethods[0]->name;
    for (process_type=processMethods; *process_type; process_type++)
        if (!strcasecmp(*name, (*process_type)->name))
            return *process_type;
    return ((void *)0);
}

canonical_original_code:
struct process_method_t *getProcessMethod(char **name) {
    struct process_method_t **process_type;
    if (!*name)
        *name = processMethods[0]->name;
    for (process_type=processMethods; *process_type; process_type++)
        if (!strcasecmp(*name, (*process_type)->name))
            return *process_type;
    return ((void *)0);
}

variable_types:
name
char **

variable_types: struct process_method_t { void (*help)(); char *name; int (*init)(); void (*deinit)(); int (*compileVolumeCommand)(long *volumeLevel); int (*compileDeviceCommand)(char *header, char *action); int (*processCommand)(void *event_header, void *event); int (*strip_raw_input)(unsigned char *device_status_message, long bytes_read); } **


initMsQ

decompiled_code:
__int64 initMsQ()
{
FILE *v0; // rax
key_t v1; // edi
int v2; // eax
unsigned int v3; // er8
__int64 result; // rax
int *v5; // rax
char *v6; // rax
int *v7; // rax
char *v8; // rax
int *v9; // rax
char *v10; // rax
int *v11; // rax
char *v12; // rax

v0 = fopen("/tmp/synchronator.msq", "w");
if ( v0 )
{
fclose(v0);
if ( chmod("/tmp/synchronator.msq", 0x192u) == -1 )
{
v9 = _errno_location();
v10 = strerror(*v9);
syslog(3, "Failed to set permissions message queue location: %s", v10);
result = 1LL;
}
else
{
v1 = ftok("/tmp/synchronator.msq", 66);
if ( v1 == -1 )
{
v11 = _errno_location();
v12 = strerror(*v11);
syslog(3, "Failed to generate token: %s", v12);
result = 1LL;
}
else
{
v2 = msgget(v1, 950);
v3 = 0;
msq_id = v2;
if ( v2 == -1 )
{
v5 = _errno_location();
v6 = strerror(*v5);
syslog(3, "Failed to create message queue: %s", v6);
v3 = 1;
}
result = v3;
}
}
}
else
{
v7 = _errno_location();
v8 = strerror(*v7);
syslog(3, "Failed to create message queue location: %s", v8);
result = 1LL;
}
return result;
}

canonical_decompiled_code:
__int64 func0()
{
FILE *v0; // rax
key_t v1; // edi
int v2; // eax
unsigned int v3; // er8
__int64 result; // rax
int *v5; // rax
char *v6; // rax
int *v7; // rax
char *v8; // rax
int *v9; // rax
char *v10; // rax
int *v11; // rax
char *v12; // rax

v0 = fopen("/tmp/synchronator.msq", "w");
if ( v0 )
{
fclose(v0);
if ( chmod("/tmp/synchronator.msq", 0x192u) == -1 )
{
v9 = _errno_location();
v10 = strerror(*v9);
syslog(3, "Failed to set permissions message queue location: %s", v10);
result = 1LL;
}
else
{
v1 = ftok("/tmp/synchronator.msq", 66);
if ( v1 == -1 )
{
v11 = _errno_location();
v12 = strerror(*v11);
syslog(3, "Failed to generate token: %s", v12);
result = 1LL;
}
else
{
v2 = msgget(v1, 950);
v3 = 0;
msq_id = v2;
if ( v2 == -1 )
{
v5 = _errno_location();
v6 = strerror(*v5);
syslog(3, "Failed to create message queue: %s", v6);
v3 = 1;
}
result = v3;
}
}
}
else
{
v7 = _errno_location();
v8 = strerror(*v7);
syslog(3, "Failed to create message queue location: %s", v8);
result = 1LL;
}
return result;
}

original_code:
int initMsQ(void) {
    key_t msq_key;
    if((msq_file = fopen("/tmp/" "synchronator" ".msq","w")) != ((void *)0)) {
        fclose(msq_file);
        if(-1 == chmod("/tmp/" "synchronator" ".msq", 0200 | 0400 | (0200 >> 3) | ((0200 >> 3) >> 3))) {
            syslog(3, "Failed to set permissions message queue location: %s", strerror((*__errno_location ())));
            return 1;
        }
    }
    else {
        syslog(3, "Failed to create message queue location: %s", strerror((*__errno_location ())));
        return 1;
    }
    if((msq_key = ftok("/tmp/" "synchronator" ".msq", 'B')) == -1) {
        syslog(3, "Failed to generate token: %s", strerror((*__errno_location ())));
        return 1;
    }
    if((msq_id = msgget(msq_key, 0666 | 01000)) == -1) {
        syslog(3, "Failed to create message queue: %s", strerror((*__errno_location ())));
        return 1;
    }
    return 0;
}

canonical_original_code:
int initMsQ() {
    int msq_key;
    if((msq_file = fopen("/tmp/" "synchronator" ".msq","w")) != ((void *)0)) {
        fclose(msq_file);
        if(-1 == chmod("/tmp/" "synchronator" ".msq", 0200 | 0400 | (0200 >> 3) | ((0200 >> 3) >> 3))) {
            syslog(3, "Failed to set permissions message queue location: %s", strerror((*__errno_location ())));
            return 1;
        }
    }
    else {
        syslog(3, "Failed to create message queue location: %s", strerror((*__errno_location ())));
        return 1;
    }
    if((msq_key = ftok("/tmp/" "synchronator" ".msq", 'B')) == -1) {
        syslog(3, "Failed to generate token: %s", strerror((*__errno_location ())));
        return 1;
    }
    if((msq_id = msgget(msq_key, 0666 | 01000)) == -1) {
        syslog(3, "Failed to create message queue: %s", strerror((*__errno_location ())));
        return 1;
    }
    return 0;
}


deinitMsQ

decompiled_code:
void deinitMsQ()
{
int *v0; // rax
char *v1; // rax
int *v2; // rax
char *v3; // rax

if ( msq_id >= 0 )
{
if ( msgctl(msq_id, 0, 0LL) == -1 )
{
v0 = _errno_location();
v1 = strerror(*v0);
syslog(4, "Unable to remove message queue: %s", v1);
}
if ( remove("/tmp/synchronator.msq") == -1 )
{
v2 = _errno_location();
v3 = strerror(*v2);
syslog(4, "Unable to delete message queue location: %s", v3);
}
}
}

canonical_decompiled_code:
void func2()
{
int *v0; // rax
char *v1; // rax
int *v2; // rax
char *v3; // rax

if ( msq_id >= 0 )
{
if ( msgctl(msq_id, 0, 0LL) == -1 )
{
v0 = _errno_location();
v1 = strerror(*v0);
syslog(4, "Unable to remove message queue: %s", v1);
}
if ( remove("/tmp/synchronator.msq") == -1 )
{
v2 = _errno_location();
v3 = strerror(*v2);
syslog(4, "Unable to delete message queue location: %s", v3);
}
}
}

original_code:
void deinitMsQ(void) {
    if(msq_id >= 0) {
        if(msgctl(msq_id, 0, ((void *)0)) == -1)
            syslog(4, "Unable to remove message queue: %s", strerror((*__errno_location ())));
        if(remove("/tmp/" "synchronator" ".msq") == -1)
            syslog(4, "Unable to delete message queue location: %s", strerror((*__errno_location ())));
    }
}

canonical_original_code:
void deinitMsQ() {
    if(msq_id >= 0) {
        if(msgctl(msq_id, 0, ((void *)0)) == -1)
            syslog(4, "Unable to remove message queue: %s", strerror((*__errno_location ())));
        if(remove("/tmp/" "synchronator" ".msq") == -1)
            syslog(4, "Unable to delete message queue location: %s", strerror((*__errno_location ())));
    }
}


decompiled_code:
void __fastcall convertInternal2External(_QWORD *a1, double *a2)
{
*a2 = (double)(int)*a1 * *(double *)&multiplierIntToExt + (double)common_data[6];
}

canonical_decompiled_code:
void __fastcall func1(_QWORD *a1, double *a2)
{
*a2 = (double)(int)*a1 * *(double *)&multiplierIntToExt + (double)common_data[6];
}

original_code:
static void convertInternal2External(long *volumeInternal, double *volumeExternal) {
    *volumeExternal = (*volumeInternal * multiplierIntToExt) + common_data.volume_min;
}

variable_types:
volumeExternal
double *


getMixer

decompiled_code:
__int64 __fastcall getMixer(__int64 *a1)
{
const char *v2; // rax

if ( volumeNormalized )
{
*a1 = (unsigned int)(int)(get_normalized_playback_volume(snd_elem, 0LL) * 100.0);
LABEL_3:
(*(void (__fastcall **)(__int64 *))(common_data[18] + 48LL))(a1);
return 0LL;
}
if ( (int)snd_mixer_selem_get_playback_volume(snd_elem, 0LL, a1) >= 0 )
{
*a1 = 100 * (*a1 - common_data[5]) / common_data[7];
goto LABEL_3;
}
v2 = (const char *)snd_strerror(4294967294LL);
syslog(3, "Failed to get playback volume: %s (%i)", v2, 4294967294LL);
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 *a1)
{
const char *v2; // rax

if ( volumeNormalized )
{
*a1 = (unsigned int)(int)(get_normalized_playback_volume(snd_elem, 0LL) * 100.0);
LABEL_3:
(*(void (__fastcall **)(__int64 *))(common_data[18] + 48LL))(a1);
return 0LL;
}
if ( (int)snd_mixer_selem_get_playback_volume(snd_elem, 0LL, a1) >= 0 )
{
*a1 = 100 * (*a1 - common_data[5]) / common_data[7];
goto LABEL_3;
}
v2 = (const char *)snd_strerror(4294967294LL);
syslog(3, "Failed to get playback volume: %s (%i)", v2, 4294967294LL);
return 1LL;
}

original_code:
int getMixer(long *volume) {
    int status = -2;
    if(volumeNormalized) {
        *volume = 100 * get_normalized_playback_volume(snd_elem, 0);
    }
    else {
        if((snd_mixer_selem_get_playback_volume(snd_elem, 0, volume)) < 0) {
            syslog(3, "Failed to get playback volume: %s (%i)",
                snd_strerror(status), status);
            return 1;
        }
        *volume = 100 * (*volume - common_data.alsa_volume_min) / common_data.alsa_volume_range;
    }
    common_data.volume->convertMixer2Internal(volume);
    return 0;
}

variable_types:
volume
long *

variable_types: status int


setMixer

decompiled_code:
__int64 __fastcall setMixer(int a1)
{
if ( volumeNormalized )
{
if ( !(unsigned int)set_normalized_playback_volume(snd_elem, 0xFFFFFFFFLL, (double)a1 * 0.01) )
return 0LL;
}
else if ( !(unsigned int)snd_mixer_selem_set_playback_volume_all(snd_elem, a1) )
{
return 0LL;
}
syslog(4, "Setting mixer failed");
return 1LL;
}

canonical_decompiled_code:
__int64 __fastcall func2(int a1)
{
if ( volumeNormalized )
{
if ( !(unsigned int)set_normalized_playback_volume(snd_elem, 0xFFFFFFFFLL, (double)a1 * 0.01) )
return 0LL;
}
else if ( !(unsigned int)snd_mixer_selem_set_playback_volume_all(snd_elem, a1) )
{
return 0LL;
}
syslog(4, "Setting mixer failed");
return 1LL;
}

original_code:
int setMixer(int volume) {
    if(volumeNormalized) {
        if((set_normalized_playback_volume(snd_elem, 0.01 * volume, -1)) != 0) {
            syslog(4, "Setting mixer failed");
            return 1;
            syslog(3, "Volume (%i)", volume);
        }
    }
    else {
        if((snd_mixer_selem_set_playback_volume_all(snd_elem, volume)) != 0) {
            syslog(4, "Setting mixer failed");
            return 1;
        }
    }
    return 0;
}

variable_types: volume int


watchMixer

decompiled_code:
void __fastcall __noreturn watchMixer(__sigset_t *newmask)
{
int v1; // eax
unsigned int v2; // er12
__int64 v3; // r12
const char *v4; // rax
int *v5; // rax
__int64 v6[4]; // [rsp+8h] [rbp-20h] BYREF

if ( pthread_sigmask(0, newmask, 0LL) < 0 )
{
v5 = _errno_location();
syslog(3, "Failed to ignore signals in watchMixer: %i", (unsigned int)*v5);
pthread_kill(mainThread, 15);
pause();
}
v6[0] = -1LL;
if ( LODWORD(common_data[0]) || !HIDWORD(common_data[0]) )
{
while ( 1 )
{
do
{
v1 = snd_mixer_wait(snd_handle, 0xFFFFFFFFLL);
v2 = v1;
if ( v1 < 0 )
{
v4 = (const char *)snd_strerror((unsigned int)v1);
syslog(3, "Failed waiting for mixer event: %s (%i)", v4, v2);
pthread_kill(mainThread, 15);
pause();
}
snd_mixer_handle_events(snd_handle);
v3 = v6[0];
if ( (unsigned int)getMixer(v6) == 1 )
{
pthread_kill(mainThread, 15);
pause();
}
}
while ( v6[0] == v3 );
LABEL_10:
if ( (*(unsigned int (__fastcall **)(__int64 *))(common_data[16] + 32LL))(v6) == 1 )
{
pthread_kill(mainThread, 15);
pause();
}
}
}
if ( (unsigned int)getMixer(v6) == 1 )
{
pthread_kill(mainThread, 15);
pause();
}
goto LABEL_10;
}

canonical_decompiled_code:
void __fastcall __noreturn func4(__sigset_t *newmask)
{
int v1; // eax
unsigned int v2; // er12
__int64 v3; // r12
const char *v4; // rax
int *v5; // rax
__int64 v6[4]; // [rsp+8h] [rbp-20h] BYREF

if ( pthread_sigmask(0, newmask, 0LL) < 0 )
{
v5 = _errno_location();
syslog(3, "Failed to ignore signals in watchMixer: %i", (unsigned int)*v5);
pthread_kill(mainThread, 15);
pause();
}
v6[0] = -1LL;
if ( LODWORD(common_data[0]) || !HIDWORD(common_data[0]) )
{
while ( 1 )
{
do
{
v1 = snd_mixer_wait(snd_handle, 0xFFFFFFFFLL);
v2 = v1;
if ( v1 < 0 )
{
v4 = (const char *)snd_strerror((unsigned int)v1);
syslog(3, "Failed waiting for mixer event: %s (%i)", v4, v2);
pthread_kill(mainThread, 15);
pause();
}
snd_mixer_handle_events(snd_handle);
v3 = v6[0];
if ( (unsigned int)func1(v6) == 1 )
{
pthread_kill(mainThread, 15);
pause();
}
}
while ( v6[0] == v3 );
LABEL_10:
if ( (*(unsigned int (__fastcall **)(__int64 *))(common_data[16] + 32LL))(v6) == 1 )
{
pthread_kill(mainThread, 15);
pause();
}
}
}
if ( (unsigned int)func1(v6) == 1 )
{
pthread_kill(mainThread, 15);
pause();
}
goto LABEL_10;
}

original_code:
void *watchMixer(void *arg) {
    sigset_t *thread_sigmask = (sigset_t *)arg;
    if(pthread_sigmask(0, thread_sigmask, ((void *)0)) < 0) {
        syslog(3, "Failed to ignore signals in watchMixer: %i", (*__errno_location ()));
        pthread_kill(mainThread, 15);
        pause();
    }
    long volume = -1;
    long volume_old = -1;
    int status = -2;
    int events = -1;
    if(!common_data.sync_2way && common_data.discrete_volume) {
        if(getMixer(&volume) == 1) {
            pthread_kill(mainThread, 15);
            pause();
        }
        if(common_data.process->compileVolumeCommand(&volume) == 1) {
            pthread_kill(mainThread, 15);
            pause();
        }
    }
    while(1) {
        if((status = snd_mixer_wait(snd_handle, -1)) < 0) {
            syslog(3, "Failed waiting for mixer event: %s (%i)",
                snd_strerror(status), status);
            pthread_kill(mainThread, 15);
            pause();
        }
        events = snd_mixer_handle_events(snd_handle);
        volume_old = volume;
        if(getMixer(&volume) == 1) {
            pthread_kill(mainThread, 15);
            pause();
        }
        if(volume == volume_old)
            continue;
        if(common_data.process->compileVolumeCommand(&volume) == 1) {
            pthread_kill(mainThread, 15);
            pause();
        }
        }
    pthread_kill(mainThread, 15);
    pause();
}

canonical_original_code:
void *watchMixer(void *arg) {
    struct __sigset_t *thread_sigmask = (sigset_t *)arg;
    if(pthread_sigmask(0, thread_sigmask, ((void *)0)) < 0) {
        syslog(3, "Failed to ignore signals in watchMixer: %i", (*__errno_location ()));
        pthread_kill(mainThread, 15);
        pause();
    }
    long volume = -1;
    long volume_old = -1;
    int status = -2;
    int events = -1;
    if(!common_data.sync_2way && common_data.discrete_volume) {
        if(getMixer(&volume) == 1) {
            pthread_kill(mainThread, 15);
            pause();
        }
        if(common_data.process->compileVolumeCommand(&volume) == 1) {
            pthread_kill(mainThread, 15);
            pause();
        }
    }
    while(1) {
        if((status = snd_mixer_wait(snd_handle, -1)) < 0) {
            syslog(3, "Failed waiting for mixer event: %s (%i)",
                snd_strerror(status), status);
            pthread_kill(mainThread, 15);
            pause();
        }
        events = snd_mixer_handle_events(snd_handle);
        volume_old = volume;
        if(getMixer(&volume) == 1) {
            pthread_kill(mainThread, 15);
            pause();
        }
        if(volume == volume_old)
            continue;
        if(common_data.process->compileVolumeCommand(&volume) == 1) {
            pthread_kill(mainThread, 15);
            pause();
        }
        }
    pthread_kill(mainThread, 15);
    pause();
}

variable_types:
arg
void *

variable_types: struct __sigset_t { unsigned long __val[-1]; } *

variable_types: volume long

variable_types: events int


deinitMixer

decompiled_code:
__int64 deinitMixer()
{
__int64 result; // rax

if ( snd_handle )
result = snd_mixer_close();
return result;
}

canonical_decompiled_code:
__int64 func5()
{
__int64 result; // rax

if ( snd_handle )
result = snd_mixer_close();
return result;
}

original_code:
void deinitMixer(void) {
    if(snd_handle != ((void *)0))
        snd_mixer_close(snd_handle);
}

canonical_original_code:
void deinitMixer() {
    if(snd_handle != ((void *)0))
        snd_mixer_close(snd_handle);
}


reinit

decompiled_code:
__int64 reinit()
{
int v0; // eax
double v1; // xmm0_8
__int64 v2; // rax
double v4[2]; // [rsp+0h] [rbp-10h] BYREF

v0 = common_data[21];
if ( v0 >= SLODWORD(common_data[4]) )
{
v1 = (double)v0;
v2 = common_data[18];
v4[0] = v1;
(*(void (__fastcall **)(double *))(v2 + 40))(v4);
setMixer((int)v4[0]);
}
return 0LL;
}

canonical_decompiled_code:
__int64 func3()
{
int v0; // eax
double v1; // xmm0_8
__int64 v2; // rax
double v4[2]; // [rsp+0h] [rbp-10h] BYREF

v0 = common_data[21];
if ( v0 >= SLODWORD(common_data[4]) )
{
v1 = (double)v0;
v2 = common_data[18];
v4[0] = v1;
(*(void (__fastcall **)(double *))(v2 + 40))(v4);
func2((int)v4[0]);
}
return 0LL;
}

original_code:
static int reinit(void) {
    if(common_data.defaultExternalVolume < common_data.initial_volume_min)
        return 0;
    double defaultVolume = common_data.defaultExternalVolume;
    common_data.volume->convertExternal2Mixer(&defaultVolume);
    setMixer((int)defaultVolume);
    return 0;
}

canonical_original_code:
static int reinit() {
    if(common_data.defaultExternalVolume < common_data.initial_volume_min)
        return 0;
    double defaultVolume = common_data.defaultExternalVolume;
    common_data.volume->convertExternal2Mixer(&defaultVolume);
    setMixer((int)defaultVolume);
    return 0;
}

variable_types: defaultVolume double


decompiled_code:
bool __fastcall use_linear_dB_scale(__int64 a1, __int64 a2)
{
return a2 - a1 <= 2400;
}

canonical_decompiled_code:
bool __fastcall func0(__int64 a1, __int64 a2)
{
return a2 - a1 <= 2400;
}

original_code:
static inline _Bool use_linear_dB_scale(long dBmin, long dBmax)
{
 return dBmax - dBmin <= 24 * 100;
}

variable_types: dBmin long

variable_types: dBmax long


original_code:
static long lrint_dir(double x, int dir)
{
 if (dir > 0)
  return lrint(ceil(x));
 else if (dir < 0)
  return lrint(floor(x));
 else
  return lrint(x);
}

variable_types: x double

variable_types: dir int

return_type: long


processUpper

decompiled_code:
void __fastcall processUpper(double *a1)
{
if ( *a1 > (double)responseLimit )
*a1 = *a1 / *(double *)&responseDivisor;
}

canonical_decompiled_code:
void __fastcall func0(double *a1)
{
if ( *a1 > (double)responseLimit )
*a1 = *a1 / *(double *)&responseDivisor;
}

original_code:
static void processUpper(double *volume_level) {
    if(*volume_level > responseLimit)
        *volume_level = *volume_level / responseDivisor;
}


processLower

decompiled_code:
void __fastcall processLower(double *a1)
{
if ( (double)responseLimit > *a1 )
*a1 = *a1 / *(double *)&responseDivisor;
}

canonical_decompiled_code:
void __fastcall func1(double *a1)
{
if ( (double)responseLimit > *a1 )
*a1 = *a1 / *(double *)&responseDivisor;
}

original_code:
static void processLower(double *volume_level) {
    if(*volume_level < responseLimit)
        *volume_level = *volume_level / responseDivisor;
}


deinit

decompiled_code:
void deinit()
{
;
}

canonical_decompiled_code:
void func2()
{
;
}

original_code:
static void deinit(void) {
}

canonical_original_code:
static void deinit() {
}


init

decompiled_code:
__int64 init()
{
const char *v1; // [rsp+8h] [rbp-10h] BYREF

if ( !(unsigned int)validateConfigString(&config, "volume.response.type", &v1, 0xFFFFFFFFLL) )
{
if ( !strcmp(v1, "lower_limit") )
{
if ( !strcmp(v1, "upper_limit") )
return 1LL;
*(&modVolumeResponseCondResize + 3) = (char *)processUpper;
}
else
{
*(&modVolumeResponseCondResize + 3) = (char *)processLower;
}
}
if ( (unsigned int)validateConfigInt(&config, "volume.response.limit", &responseLimit, 0xFFFFFFFFLL, 0LL, 0LL, -1LL) == 1
|| (unsigned int)validateConfigDouble(
&config,
"volume.response.divisor",
&responseDivisor,
0xFFFFFFFFLL,
0LL,
0LL,
-1.0) == 1 )
{
return 1LL;
}
if ( 1.0 == *(double *)&responseDivisor )
*(_QWORD *)(common_data[19] + 8LL) = 0LL;
return 0LL;
}

canonical_decompiled_code:
__int64 func3()
{
const char *v1; // [rsp+8h] [rbp-10h] BYREF

if ( !(unsigned int)validateConfigString(&config, "volume.response.type", &v1, 0xFFFFFFFFLL) )
{
if ( !strcmp(v1, "lower_limit") )
{
if ( !strcmp(v1, "upper_limit") )
return 1LL;
*(&modVolumeResponseCondResize + 3) = (char *)processUpper;
}
else
{
*(&modVolumeResponseCondResize + 3) = (char *)processLower;
}
}
if ( (unsigned int)validateConfigInt(&config, "volume.response.limit", &responseLimit, 0xFFFFFFFFLL, 0LL, 0LL, -1LL) == 1
|| (unsigned int)validateConfigDouble(
&config,
"volume.response.divisor",
&responseDivisor,
0xFFFFFFFFLL,
0LL,
0LL,
-1.0) == 1 )
{
return 1LL;
}
if ( 1.0 == *(double *)&responseDivisor )
*(_QWORD *)(common_data[19] + 8LL) = 0LL;
return 0LL;
}

original_code:
static int init(void) {
const char *type;
    if(validateConfigString(&config, "volume.response.type", &type, -1) == 0) {
        if(strcmp(type, "lower_limit"))
            modVolumeResponseCondResize.process = &processLower;
        else
        if(strcmp(type, "upper_limit"))
            modVolumeResponseCondResize.process = &processUpper;
        else
            return 1;
    }
    if(validateConfigInt(&config, "volume.response.limit", &responseLimit, -1, 0, 0, -1) == 1)
        return 1;
    if(validateConfigDouble(&config, "volume.response.divisor", &responseDivisor, -1, 0, 0, -1) == 1)
        return 1;
    if(responseDivisor == 1)
        common_data.mod->volumeResponse = ((void *)0);
    return 0;
}

canonical_original_code:
static int init() {
char *type;
    if(validateConfigString(&config, "volume.response.type", &type, -1) == 0) {
        if(strcmp(type, "lower_limit"))
            modVolumeResponseCondResize.process = &processLower;
        else
        if(strcmp(type, "upper_limit"))
            modVolumeResponseCondResize.process = &processUpper;
        else
            return 1;
    }
    if(validateConfigInt(&config, "volume.response.limit", &responseLimit, -1, 0, 0, -1) == 1)
        return 1;
    if(validateConfigDouble(&config, "volume.response.divisor", &responseDivisor, -1, 0, 0, -1) == 1)
        return 1;
    if(responseDivisor == 1)
        common_data.mod->volumeResponse = ((void *)0);
    return 0;
}

variable_types:
type
char *


help

decompiled_code:
int help()
{
return puts("Conditional Resize");
}

canonical_decompiled_code:
int func4()
{
return puts("Conditional Resize");
}

original_code:
static void help(void) {
    printf("Conditional Resize\n"
          );
}

canonical_original_code:
static void help() {
    printf("Conditional Resize\n"
          );
}


validateConfigString

decompiled_code:
__int64 __fastcall validateConfigString(__int64 a1, const char *a2, const char **a3, int a4)
{
const char *v4; // r12
__int64 result; // rax
char v7[136]; // [rsp+0h] [rbp-88h] BYREF

v4 = a2;
if ( a4 >= 0 )
{
v4 = v7;
snprintf(v7, 0x64uLL, "%s.[%i]", a2, (unsigned int)a4);
}
if ( (unsigned int)config_lookup_string(a1, v4, a3) )
{
syslog(6, "[OK] %s: %s", v4, *a3);
result = 0LL;
}
else
{
syslog(3, "[ERROR] Setting not present or formatted as string: %s", v4);
result = 1LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func0(__int64 a1, const char *a2, const char **a3, int a4)
{
const char *v4; // r12
__int64 result; // rax
char v7[136]; // [rsp+0h] [rbp-88h] BYREF

v4 = a2;
if ( a4 >= 0 )
{
v4 = v7;
snprintf(v7, 0x64uLL, "%s.[%i]", a2, (unsigned int)a4);
}
if ( (unsigned int)config_lookup_string(a1, v4, a3) )
{
syslog(6, "[OK] %s: %s", v4, *a3);
result = 0LL;
}
else
{
syslog(3, "[ERROR] Setting not present or formatted as string: %s", v4);
result = 1LL;
}
return result;
}

original_code:
int validateConfigString(config_t *config, char *configSettingSource,
const char **configSettingDestination, int position) {
    if(position >= 0) {
        char configQuery[100];
        snprintf(configQuery, 100, "%s.[%i]", configSettingSource, position);
        configSettingSource = &configQuery[0];
    }
    if(!config_lookup_string(config, configSettingSource, configSettingDestination)) {
        syslog(3, "[ERROR] Setting not present or formatted as string: %s", configSettingSource);
        return 1;
    }
    else {
        syslog(6, "[OK] %s: %s", configSettingSource, *configSettingDestination);
        return 0;
    }
}

canonical_original_code:
int validateConfigString(struct config_t *config, char *configSettingSource, char **configSettingDestination, int position) {
    if(position >= 0) {
        char configQuery[100];
        snprintf(configQuery, 100, "%s.[%i]", configSettingSource, position);
        configSettingSource = &configQuery[0];
    }
    if(!config_lookup_string(config, configSettingSource, configSettingDestination)) {
        syslog(3, "[ERROR] Setting not present or formatted as string: %s", configSettingSource);
        return 1;
    }
    else {
        syslog(6, "[OK] %s: %s", configSettingSource, *configSettingDestination);
        return 0;
    }
}

variable_types: struct config_t { struct config_setting_t { char *name; short type; short format; union config_value_t { int ival; long long llval; double fval; char *sval; struct config_list_t { unsigned int length; struct config_setting_t **elements; } *list; } value; struct config_setting_t *parent; struct config_t *config; void *hook; unsigned int line; char *file; } *root; void (*destructor)(void *); int options; unsigned short tab_width; short default_format; char *include_dir; char *error_text; char *error_file; int error_line; enum config_error_t { CONFIG_ERR_NONE=0, CONFIG_ERR_FILE_IO=1, CONFIG_ERR_PARSE=2 } error_type; char **filenames; unsigned int num_filenames; } *

variable_types:
configSettingSource
char *

variable_types:
configSettingDestination
char **

variable_types: position int

variable_types:
configQuery
char [100]

user_defined_types: struct config_t { struct config_setting_t *root; void (*destructor)(void *); int options; unsigned short tab_width; short default_format; char *include_dir; char *error_text; char *error_file; int error_line; enum config_error_t error_type; char **filenames; unsigned int num_filenames; }

user_defined_types: struct config_setting_t { char *name; short type; short format; union config_value_t value; struct config_setting_t *parent; struct config_t *config; void *hook; unsigned int line; char *file; }

user_defined_types: union config_value_t { int ival; long long llval; double fval; char *sval; struct config_list_t *list; }


validateConfigInt

decompiled_code:
__int64 __fastcall validateConfigInt(__int64 a1, const char *a2, int *a3, int a4, int a5, int a6, int a7)
{
char *v8; // r12
int v11; // er13
__int64 result; // rax
int v13; // [rsp+Ch] [rbp-ACh] BYREF
char s[168]; // [rsp+10h] [rbp-A8h] BYREF

v8 = (char *)a2;
v13 = -1;
v11 = a7;
if ( a4 >= 0 )
{
v8 = s;
snprintf(s, 0x64uLL, "%s.[%i]", a2, (unsigned int)a4);
}
if ( (unsigned int)config_lookup_int(a1, v8, &v13) )
{
v11 = v13;
}
else
{
if ( a7 == -1 )
{
syslog(3, "[ERROR] Setting not present or not an integer: %s", v8);
return 1LL;
}
if ( a7 == -2 )
{
syslog(6, "[NOTICE] Setting not found, ignoring %s", v8);
return 1LL;
}
v13 = a7;
}
if ( a6 | a5 && (a5 > v11 || a6 < v11) )
{
syslog(
3,
"[ERROR] Setting '%s' is out of range: %i [%i-%i]",
v8,
(unsigned int)v11,
(unsigned int)a5,
(unsigned int)a6);
result = 1LL;
}
else
{
*a3 = v11;
syslog(6, "[OK] %s: %i", v8, (unsigned int)v11);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func1(__int64 a1, const char *a2, int *a3, int a4, int a5, int a6, int a7)
{
char *v8; // r12
int v11; // er13
__int64 result; // rax
int v13; // [rsp+Ch] [rbp-ACh] BYREF
char s[168]; // [rsp+10h] [rbp-A8h] BYREF

v8 = (char *)a2;
v13 = -1;
v11 = a7;
if ( a4 >= 0 )
{
v8 = s;
snprintf(s, 0x64uLL, "%s.[%i]", a2, (unsigned int)a4);
}
if ( (unsigned int)config_lookup_int(a1, v8, &v13) )
{
v11 = v13;
}
else
{
if ( a7 == -1 )
{
syslog(3, "[ERROR] Setting not present or not an integer: %s", v8);
return 1LL;
}
if ( a7 == -2 )
{
syslog(6, "[NOTICE] Setting not found, ignoring %s", v8);
return 1LL;
}
v13 = a7;
}
if ( a6 | a5 && (a5 > v11 || a6 < v11) )
{
syslog(
3,
"[ERROR] Setting '%s' is out of range: %i [%i-%i]",
v8,
(unsigned int)v11,
(unsigned int)a5,
(unsigned int)a6);
result = 1LL;
}
else
{
*a3 = v11;
syslog(6, "[OK] %s: %i", v8, (unsigned int)v11);
result = 0LL;
}
return result;
}

original_code:
int validateConfigInt(config_t *config, char *configSettingSource, int *configSettingDestination,
int position, int valueMin, int valueMax, int valueDefault) {
    int configReturnedInt = -1;
    if(position >= 0) {
        char configQuery[100];
        snprintf(configQuery, 100, "%s.[%i]", configSettingSource, position);
        configSettingSource = &configQuery[0];
    }
    if(!config_lookup_int(config, configSettingSource, &configReturnedInt)) {
        if(valueDefault == -1) {
            syslog(3, "[ERROR] Setting not present or not an integer: %s", configSettingSource);
            return 1;
        }
        else if (valueDefault == -2) {
            syslog(6, "[NOTICE] Setting not found, ignoring %s", configSettingSource);
            return 1;
        }
        else
            configReturnedInt = valueDefault;
    }
    if(!(valueMin == 0 && valueMax == 0) && (configReturnedInt < valueMin || configReturnedInt > valueMax)) {
        syslog(3, "[ERROR] Setting '%s' is out of range: %i [%i-%i]", configSettingSource,
                configReturnedInt, valueMin, valueMax);
        return 1;
    }
    *configSettingDestination = configReturnedInt;
    syslog(6, "[OK] %s: %i", configSettingSource, *configSettingDestination);
    return 0;
}

canonical_original_code:
int validateConfigInt(struct config_t *config, char *configSettingSource, int *configSettingDestination, int position, int valueMin, int valueMax, int valueDefault) {
    int configReturnedInt = -1;
    if(position >= 0) {
        char configQuery[100];
        snprintf(configQuery, 100, "%s.[%i]", configSettingSource, position);
        configSettingSource = &configQuery[0];
    }
    if(!config_lookup_int(config, configSettingSource, &configReturnedInt)) {
        if(valueDefault == -1) {
            syslog(3, "[ERROR] Setting not present or not an integer: %s", configSettingSource);
            return 1;
        }
        else if (valueDefault == -2) {
            syslog(6, "[NOTICE] Setting not found, ignoring %s", configSettingSource);
            return 1;
        }
        else
            configReturnedInt = valueDefault;
    }
    if(!(valueMin == 0 && valueMax == 0) && (configReturnedInt < valueMin || configReturnedInt > valueMax)) {
        syslog(3, "[ERROR] Setting '%s' is out of range: %i [%i-%i]", configSettingSource,
                configReturnedInt, valueMin, valueMax);
        return 1;
    }
    *configSettingDestination = configReturnedInt;
    syslog(6, "[OK] %s: %i", configSettingSource, *configSettingDestination);
    return 0;
}

variable_types:
configSettingDestination
int *

variable_types: valueMin int

variable_types: valueMax int

variable_types: valueDefault int

variable_types: configReturnedInt int

user_defined_types: enum config_error_t { CONFIG_ERR_NONE=0, CONFIG_ERR_FILE_IO=1, CONFIG_ERR_PARSE=2 }

user_defined_types: struct config_list_t { unsigned int length; struct config_setting_t **elements; }


validateConfigDouble

decompiled_code:
__int64 __fastcall validateConfigDouble(__int64 a1, const char *a2, double *a3, int a4, int a5, int a6, double a7)
{
char *v8; // r12
__int64 result; // rax
double v12; // [rsp+18h] [rbp-A0h] BYREF
char s[152]; // [rsp+20h] [rbp-98h] BYREF

v8 = (char *)a2;
v12 = *(double *)&LC7;
if ( a4 >= 0 )
{
v8 = s;
snprintf(s, 0x64uLL, "%s.[%i]", a2, (unsigned int)a4);
}
if ( (unsigned int)config_lookup_float(a1, v8, &v12) )
{
a7 = v12;
}
else
{
if ( a7 == -1.0 )
{
syslog(3, "[ERROR] Setting not present or not an integer/float: %s", v8);
return 1LL;
}
if ( a7 == -2.0 )
{
syslog(6, "[NOTICE] Setting not found, ignoring %s", v8);
return 1LL;
}
v12 = a7;
}
if ( a6 | a5 && ((double)a5 > a7 || a7 > (double)a6) )
{
syslog(3, "[ERROR] Setting '%s' is out of range: %.2f [%i-%i]", v8, a7, (unsigned int)a5, (unsigned int)a6);
result = 1LL;
}
else
{
*a3 = a7;
syslog(6, "[OK] %s: %.2f", v8, a7);
result = 0LL;
}
return result;
}

canonical_decompiled_code:
__int64 __fastcall func2(__int64 a1, const char *a2, double *a3, int a4, int a5, int a6, double a7)
{
char *v8; // r12
__int64 result; // rax
double v12; // [rsp+18h] [rbp-A0h] BYREF
char s[152]; // [rsp+20h] [rbp-98h] BYREF

v8 = (char *)a2;
v12 = *(double *)&LC7;
if ( a4 >= 0 )
{
v8 = s;
snprintf(s, 0x64uLL, "%s.[%i]", a2, (unsigned int)a4);
}
if ( (unsigned int)config_lookup_float(a1, v8, &v12) )
{
a7 = v12;
}
else
{
if ( a7 == -1.0 )
{
syslog(3, "[ERROR] Setting not present or not an integer/float: %s", v8);
return 1LL;
}
if ( a7 == -2.0 )
{
syslog(6, "[NOTICE] Setting not found, ignoring %s", v8);
return 1LL;
}
v12 = a7;
}
if ( a6 | a5 && ((double)a5 > a7 || a7 > (double)a6) )
{
syslog(3, "[ERROR] Setting '%s' is out of range: %.2f [%i-%i]", v8, a7, (unsigned int)a5, (unsigned int)a6);
result = 1LL;
}
else
{
*a3 = a7;
syslog(6, "[OK] %s: %.2f", v8, a7);
result = 0LL;
}
return result;
}

original_code:
int validateConfigDouble(config_t *config, char *configSettingSource, double *configSettingDestination,
int position, int valueMin, int valueMax, double valueDefault) {
    double configReturnedDouble = -1;
    if(position >= 0) {
        char configQuery[100];
        snprintf(configQuery, 100, "%s.[%i]", configSettingSource, position);
        configSettingSource = &configQuery[0];
    }
    if(!config_lookup_float(config, configSettingSource, &configReturnedDouble)) {
        if(valueDefault == -1) {
            syslog(3, "[ERROR] Setting not present or not an integer/float: %s", configSettingSource);
            return 1;
        }
        else if (valueDefault == -2) {
            syslog(6, "[NOTICE] Setting not found, ignoring %s", configSettingSource);
            return 1;
        }
        else
            configReturnedDouble = valueDefault;
    }
    if(!(valueMin == 0 && valueMax == 0) && (configReturnedDouble < valueMin || configReturnedDouble > valueMax)) {
        syslog(3, "[ERROR] Setting '%s' is out of range: %.2f [%i-%i]", configSettingSource,
                configReturnedDouble, valueMin, valueMax);
        return 1;
    }
    *configSettingDestination = configReturnedDouble;
    syslog(6, "[OK] %s: %.2f", configSettingSource, *configSettingDestination);
    return 0;
}

canonical_original_code:
int validateConfigDouble(struct config_t *config, char *configSettingSource, double *configSettingDestination, int position, int valueMin, int valueMax, double valueDefault) {
    double configReturnedDouble = -1;
    if(position >= 0) {
        char configQuery[100];
        snprintf(configQuery, 100, "%s.[%i]", configSettingSource, position);
        configSettingSource = &configQuery[0];
    }
    if(!config_lookup_float(config, configSettingSource, &configReturnedDouble)) {
        if(valueDefault == -1) {
            syslog(3, "[ERROR] Setting not present or not an integer/float: %s", configSettingSource);
            return 1;
        }
        else if (valueDefault == -2) {
            syslog(6, "[NOTICE] Setting not found, ignoring %s", configSettingSource);
            return 1;
        }
        else
            configReturnedDouble = valueDefault;
    }
    if(!(valueMin == 0 && valueMax == 0) && (configReturnedDouble < valueMin || configReturnedDouble > valueMax)) {
        syslog(3, "[ERROR] Setting '%s' is out of range: %.2f [%i-%i]", configSettingSource,
                configReturnedDouble, valueMin, valueMax);
        return 1;
    }
    *configSettingDestination = configReturnedDouble;
    syslog(6, "[OK] %s: %.2f", configSettingSource, *configSettingDestination);
    return 0;
}

variable_types:
configSettingDestination
double *

variable_types: valueDefault double

variable_types: configReturnedDouble double


validateConfigBool

decompiled_code:
__int64 __fastcall validateConfigBool(__int64 a1, const char *a2, int *a3, int a4)
{
__int64 v7[5]; // [rsp+0h] [rbp-28h]

v7[0] = (__int64)"FALSE";
v7[1] = (__int64)"TRUE";
if ( (unsigned int)config_lookup_bool(a1, a2) )
syslog(6, "[OK] %s: %s", a2, (const char *)v7[*a3]);
else
*a3 = a4;
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func3(__int64 a1, const char *a2, int *a3, int a4)
{
__int64 v7[5]; // [rsp+0h] [rbp-28h]

v7[0] = (__int64)"FALSE";
v7[1] = (__int64)"TRUE";
if ( (unsigned int)config_lookup_bool(a1, a2) )
syslog(6, "[OK] %s: %s", a2, (const char *)v7[*a3]);
else
*a3 = a4;
return 0LL;
}

original_code:
int validateConfigBool(config_t *config, char *configSettingSource, int *configSettingDestination,
int valueDefault) {
    const char* boolNaming[2];
    boolNaming[0] = "FALSE";
    boolNaming[1] = "TRUE";
    if(!config_lookup_bool(config, configSettingSource, configSettingDestination))
        *configSettingDestination = valueDefault;
    else {
        syslog(6, "[OK] %s: %s", configSettingSource, boolNaming[*configSettingDestination]);
        return 0;
    }
    return 0;
}

canonical_original_code:
int validateConfigBool(struct config_t *config, char *configSettingSource, int *configSettingDestination, int valueDefault) {
    char *boolNaming[2];
    boolNaming[0] = "FALSE";
    boolNaming[1] = "TRUE";
    if(!config_lookup_bool(config, configSettingSource, configSettingDestination))
        *configSettingDestination = valueDefault;
    else {
        syslog(6, "[OK] %s: %s", configSettingSource, boolNaming[*configSettingDestination]);
        return 0;
    }
    return 0;
}

variable_types:
boolNaming
char *[2]


deinitVolume

decompiled_code:
__int64 deinitVolume()
{
__int64 result; // rax

result = *(_QWORD *)(*((_QWORD *)&common_data + 19) + 8LL);
if ( result )
result = (*(__int64 (**)(void))(result + 32))();
return result;
}

canonical_decompiled_code:
__int64 func0()
{
__int64 result; // rax

result = *(_QWORD *)(*((_QWORD *)&common_data + 19) + 8LL);
if ( result )
result = (*(__int64 (**)(void))(result + 32))();
return result;
}

original_code:
static void deinitVolume(void) {
    if(common_data.mod->volumeResponse != ((void *)0))
        common_data.mod->volumeResponse->deinit();
}

canonical_original_code:
static void deinitVolume() {
    if(common_data.mod->volumeResponse != ((void *)0))
        common_data.mod->volumeResponse->deinit();
}


processVolume

decompiled_code:
__int64 __fastcall processVolume(double *a1)
{
__int64 v1; // rdx
__m128d v2; // xmm0
__int64 v3; // rax
int v4; // edx
int v5; // eax
int v6; // edx
int v7; // eax
__m128d v9; // xmm3
__m128d v10; // xmm1
__int64 v11; // rax
__m128d v12; // xmm3
__int64 v13[2]; // [rsp+0h] [rbp-10h] BYREF

if ( *((_QWORD *)&common_data + 6) != *((_QWORD *)&common_data + 5) )
{
pthread_setcancelstate(1, 0LL);
if ( pthread_mutex_trylock(&lockProcess) )
{
pthread_setcancelstate(0, 0LL);
syslog(7, "Skipping incoming volume command");
return 0LL;
}
clock_gettime(1, &timestampCurrent);
v1 = (unsigned int)(LODWORD(timestampCurrent.tv_sec) - *((_DWORD *)&common_data + 24));
if ( (int)v1 <= 2 )
{
syslog(7, "Incoming volume level processing timeout (completed): %i/%i", v1, 2LL);
}
else
{
v2.m128d_f64[0] = *a1;
v3 = *(_QWORD *)(*((_QWORD *)&common_data + 19) + 8LL);
v13[0] = *(__int64 *)a1;
if ( v3 )
{
(*(void (__fastcall **)(__int64 *))(v3 + 24))(v13);
*(_QWORD *)&v2.m128d_f64[0] = v13[0];
}
v4 = *((_DWORD *)&common_data + 7);
v5 = *((_DWORD *)&common_data + 9);
if ( v2.m128d_f64[0] <= (double)v4 && (v4 == v5 || (double)v4 <= v2.m128d_f64[0]) )
{
v6 = *((_DWORD *)&common_data + 6);
v7 = *((_DWORD *)&common_data + 8);
if ( (double)v6 <= v2.m128d_f64[0] && (v6 == v7 || v2.m128d_f64[0] <= (double)v6) )
{
if ( (int)v2.m128d_f64[0] == (int)*((double *)&common_data + 8) )
goto LABEL_21;
}
else
{
if ( (double)v7 > v2.m128d_f64[0] )
{
if ( COERCE_DOUBLE(*(_QWORD *)&v2.m128d_f64[0] & LC3) < 4.503599627370496e15 )
{
v12.m128d_f64[0] = (double)(int)v2.m128d_f64[0];
*(_QWORD *)&v2.m128d_f64[0] = COERCE_UNSIGNED_INT64(v12.m128d_f64[0] - COERCE_DOUBLE(*(_OWORD *)&_mm_cmpgt_sd(v12, v2) & LC4)) | ~LC3 & *(_QWORD *)&v2.m128d_f64[0];
}
v7 = (int)v2.m128d_f64[0];
}
*((_DWORD *)&common_data + 6) = v7;
(*(void (**)(void))(*((_QWORD *)&common_data + 18) + 32LL))();
syslog(
7,
"Volume level lower range has been adjusted: %i -> %i",
*((unsigned int *)&common_data + 8),
*((unsigned int *)&common_data + 6));
*(_QWORD *)&v2.m128d_f64[0] = v13[0];
}
}
else
{
if ( v2.m128d_f64[0] > (double)v5 )
{
if ( COERCE_DOUBLE(*(_QWORD *)&v2.m128d_f64[0] & LC3) < 4.503599627370496e15 )
{
v9.m128d_f64[0] = v2.m128d_f64[0];
v10.m128d_f64[0] = (double)(int)v2.m128d_f64[0];
*(_QWORD *)&v2.m128d_f64[0] = COERCE_UNSIGNED_INT64(v10.m128d_f64[0] + COERCE_DOUBLE(*(_OWORD *)&_mm_cmpgt_sd(v9, v10) & LC4)) | ~LC3 & *(_QWORD *)&v2.m128d_f64[0];
}
v5 = (int)v2.m128d_f64[0];
}
*((_DWORD *)&common_data + 7) = v5;
(*(void (**)(void))(*((_QWORD *)&common_data + 18) + 32LL))();
syslog(
7,
"Volume upper range has been adjusted: %i -> %i",
*((unsigned int *)&common_data + 9),
*((unsigned int *)&common_data + 7));
*(_QWORD *)&v2.m128d_f64[0] = v13[0];
}
v11 = *((_QWORD *)&common_data + 18);
*((_QWORD *)&common_data + 8) = *(_QWORD *)&v2.m128d_f64[0];
(*(void (__fastcall **)(__int64 *))(v11 + 40))(v13);
setMixer((unsigned int)(int)*(double *)v13);
clock_gettime(1, (struct timespec *)(unsigned int)((_DWORD)&common_data + 80));
syslog(
7,
"Volume level mutation (ext. initiated): ext. (int.): %.2f (%.2f)",
*((double *)&common_data + 8),
*(double *)v13);
}
LABEL_21:
pthread_mutex_unlock(&lockProcess);
pthread_setcancelstate(0, 0LL);
return 0LL;
}
return 0LL;
}

canonical_decompiled_code:
__int64 __fastcall func1(double *a1)
{
__int64 v1; // rdx
__m128d v2; // xmm0
__int64 v3; // rax
int v4; // edx
int v5; // eax
int v6; // edx
int v7; // eax
__m128d v9; // xmm3
__m128d v10; // xmm1
__int64 v11; // rax
__m128d v12; // xmm3
__int64 v13[2]; // [rsp+0h] [rbp-10h] BYREF

if ( *((_QWORD *)&common_data + 6) != *((_QWORD *)&common_data + 5) )
{
pthread_setcancelstate(1, 0LL);
if ( pthread_mutex_trylock(&lockProcess) )
{
pthread_setcancelstate(0, 0LL);
syslog(7, "Skipping incoming volume command");
return 0LL;
}
clock_gettime(1, &timestampCurrent);
v1 = (unsigned int)(LODWORD(timestampCurrent.tv_sec) - *((_DWORD *)&common_data + 24));
if ( (int)v1 <= 2 )
{
syslog(7, "Incoming volume level processing timeout (completed): %i/%i", v1, 2LL);
}
else
{
v2.m128d_f64[0] = *a1;
v3 = *(_QWORD *)(*((_QWORD *)&common_data + 19) + 8LL);
v13[0] = *(__int64 *)a1;
if ( v3 )
{
(*(void (__fastcall **)(__int64 *))(v3 + 24))(v13);
*(_QWORD *)&v2.m128d_f64[0] = v13[0];
}
v4 = *((_DWORD *)&common_data + 7);
v5 = *((_DWORD *)&common_data + 9);
if ( v2.m128d_f64[0] <= (double)v4 && (v4 == v5 || (double)v4 <= v2.m128d_f64[0]) )
{
v6 = *((_DWORD *)&common_data + 6);
v7 = *((_DWORD *)&common_data + 8);
if ( (double)v6 <= v2.m128d_f64[0] && (v6 == v7 || v2.m128d_f64[0] <= (double)v6) )
{
if ( (int)v2.m128d_f64[0] == (int)*((double *)&common_data + 8) )
goto LABEL_21;
}
else
{
if ( (double)v7 > v2.m128d_f64[0] )
{
if ( COERCE_DOUBLE(*(_QWORD *)&v2.m128d_f64[0] & LC3) < 4.503599627370496e15 )
{
v12.m128d_f64[0] = (double)(int)v2.m128d_f64[0];
*(_QWORD *)&v2.m128d_f64[0] = COERCE_UNSIGNED_INT64(v12.m128d_f64[0] - COERCE_DOUBLE(*(_OWORD *)&_mm_cmpgt_sd(v12, v2) & LC4)) | ~LC3 & *(_QWORD *)&v2.m128d_f64[0];
}
v7 = (int)v2.m128d_f64[0];
}
*((_DWORD *)&common_data + 6) = v7;
(*(void (**)(void))(*((_QWORD *)&common_data + 18) + 32LL))();
syslog(
7,
"Volume level lower range has been adjusted: %i -> %i",
*((unsigned int *)&common_data + 8),
*((unsigned int *)&common_data + 6));
*(_QWORD *)&v2.m128d_f64[0] = v13[0];
}
}
else
{
if ( v2.m128d_f64[0] > (double)v5 )
{
if ( COERCE_DOUBLE(*(_QWORD *)&v2.m128d_f64[0] & LC3) < 4.503599627370496e15 )
{
v9.m128d_f64[0] = v2.m128d_f64[0];
v10.m128d_f64[0] = (double)(int)v2.m128d_f64[0];
*(_QWORD *)&v2.m128d_f64[0] = COERCE_UNSIGNED_INT64(v10.m128d_f64[0] + COERCE_DOUBLE(*(_OWORD *)&_mm_cmpgt_sd(v9, v10) & LC4)) | ~LC3 & *(_QWORD *)&v2.m128d_f64[0];
}
v5 = (int)v2.m128d_f64[0];
}
*((_DWORD *)&common_data + 7) = v5;
(*(void (**)(void))(*((_QWORD *)&common_data + 18) + 32LL))();
syslog(
7,
"Volume upper range has been adjusted: %i -> %i",
*((unsigned int *)&common_data + 9),
*((unsigned int *)&common_data + 7));
*(_QWORD *)&v2.m128d_f64[0] = v13[0];
}
v11 = *((_QWORD *)&common_data + 18);
*((_QWORD *)&common_data + 8) = *(_QWORD *)&v2.m128d_f64[0];
(*(void (__fastcall **)(__int64 *))(v11 + 40))(v13);
setMixer((unsigned int)(int)*(double *)v13);
clock_gettime(1, (struct timespec *)(unsigned int)((_DWORD)&common_data + 80));
syslog(
7,
"Volume level mutation (ext. initiated): ext. (int.): %.2f (%.2f)",
*((double *)&common_data + 8),
*(double *)v13);
}
LABEL_21:
pthread_mutex_unlock(&lockProcess);
pthread_setcancelstate(0, 0LL);
return 0LL;
}
return 0LL;
}

original_code:
static int processVolume(double *volumeExternal) {
    if(common_data.alsa_volume_max == common_data.alsa_volume_min)
        return 0;
    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, ((void *)0));
    if(pthread_mutex_trylock(&lockProcess) != 0) {
        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, ((void *)0));
        syslog(7, "Skipping incoming volume command");
        return 0;
    }
    int timeout;
    clock_gettime(1, &timestampCurrent);
    if((timeout = timestampCurrent.tv_sec - common_data.timestampLastTX.tv_sec) <= 2) {
        syslog(7, "Incoming volume level processing timeout (completed): %i/%i", timeout, 2);
        pthread_mutex_unlock(&lockProcess);
        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, ((void *)0));
        return 0;
    }
    double volume_level = *volumeExternal;
    if(common_data.mod->volumeResponse)
        common_data.mod->volumeResponse->process(&volume_level);
    if(volume_level > common_data.volume_max || common_data.volume_max != common_data.initial_volume_max
    && volume_level < common_data.volume_max) {
        if(volume_level > common_data.initial_volume_max)
            common_data.volume_max = (int)ceil(volume_level);
        else
            common_data.volume_max = common_data.initial_volume_max;
        common_data.volume->regenerateMultipliers();
        syslog(7, "Volume upper range has been adjusted: %i -> %i",
        common_data.initial_volume_max, common_data.volume_max);
    }
    else if(volume_level < common_data.volume_min || common_data.volume_min != common_data.initial_volume_min
    && volume_level > common_data.volume_min) {
        if(volume_level < common_data.initial_volume_min)
            common_data.volume_min = (int)floor(volume_level);
        else
            common_data.volume_min = common_data.initial_volume_min;
        common_data.volume->regenerateMultipliers();
        syslog(7, "Volume level lower range has been adjusted: %i -> %i",
        common_data.initial_volume_min, common_data.volume_min);
    }
    else if((int)volume_level == (int)common_data.volume_level_status) {
        pthread_mutex_unlock(&lockProcess);
        pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, ((void *)0));
        return 0;
    }
    common_data.volume_level_status = volume_level;
    common_data.volume->convertExternal2Mixer(&volume_level);
    setMixer((int)volume_level);
    clock_gettime(1 , &common_data.timestampLastRX);
    syslog(7, "Volume level mutation (ext. initiated): ext. (int.): %.2f (%.2f)", common_data.volume_level_status, volume_level);
    pthread_mutex_unlock(&lockProcess);
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, ((void *)0));
    return 0;
}

variable_types:
volumeExternal
double *

variable_types: timeout int