#!/usr/bin/env bash

# Exit on error
set -e

# Number of parallel jobs
jobs=12

# Query OS and machine
uname=`uname`
machine=`gcc -dumpmachine`

# Standard CFLAGS
cflags="-O3 -DNDEBUG"

if [[ $uname == Darwin ]] && [[ $BUILD_PPC == True ]]; then
  cflags="$cflags -arch ppc -mcpu=G4"
  ldflags="-Wl,-x -arch ppc"
  ppc=true
elif [[ $uname == Darwin ]] && [[ $BUILD_X86 == True ]]; then
  cflags="$cflags -arch i386 -march=prescott"
  ldflags="-Wl,-x -arch i386"
  x86=true
elif [[ $uname == Darwin ]] && [[ $BUILD_ARM64 == True ]]; then
  cflags="$cflags -arch arm64"
  ldflags="-Wl,-x -arch arm64"
  host="aarch64-apple-darwin20.1.0"
  arm64=true
elif [[ $uname == Darwin ]]; then
  if [[ $BUILD_MACOS11 == True ]]; then
    cflags="$cflags -arch x86_64 -march=haswell"
  else
    cflags="$cflags -arch x86_64 -march=core2"
  fi
  ldflags="-Wl,-x -arch x86_64"
  x86_64=true
elif [[ $machine == *amd64* || $machine == *x86_64* ]] && [[ $BUILD_X86 != True ]] && [[ $uname != *MINGW* || $BUILD_X86_64 == True ]]; then
  cflags="$cflags -m64 -march=nocona -mno-sse3"
  ldflags="-m64"
  x86_64=true
elif [[ $machine == *aarch64* ]]; then
  cflags="$cflags -I/usr/local/include -march=armv8-a+simd"
  arm64=true
elif [[ $machine == *arm* ]]; then
  cflags="$cflags -I/usr/local/include -march=armv7-a"
  arm=true
else
  cflags="$cflags -m32 -march=pentium4"
  ldflags="-m32"
  x86=true
fi

cflags_unroll="-funroll-loops"

# Set host triple on Linux
if [[ $uname == Linux ]]; then
  if [[ $x86_64 == true ]]; then
    host="x86_64-linux-gnu"
  elif [[ $x86 == true ]]; then
    host="i386-linux-gnu"
  elif [[ $arm64 == true ]]; then
    host="aarch64-linux-gnu"
  elif [[ $arm == true ]]; then
    host="arm-linux-gnueabihf"
  fi
fi

# Set compiler and tools
if [[ $uname != *FreeBSD* ]]; then
  export CC=gcc
  export CXX=gcc
  export MAKE=make
  export SUDO=sudo
  export DL="wget -O"
  export PATCH="patch --binary"
else
  export CC=clang
  export CXX=clang
  export MAKE=gmake
  export SUDO=sudo
  export DL="wget -O"
  export PATCH=patch
fi

if [[ $uname == Haiku ]]; then
  export SUDO=
fi

if [[ $uname == Darwin ]]; then
  export DL="curl -L -o"
fi

# Setup environment
export CFLAGS="$cflags $cflags_unroll"
export LDFLAGS="$ldflags"

if [[ $uname == *MINGW* ]]; then
  execext=exe
  sharedext=dll
  sharedinfix=-*
else
  execext=
  sharedext=so
  sharedinfix=
fi

if [[ $uname == Haiku ]]; then
  prefix="--prefix=/system/non-packaged"
fi

# Package versions
exhale_version=1.1.0
faac_version=1.30
faad2_version=2.10.0
fdk_aac_version=2.0.1
ffmpeg_version=4.3.1
flac_version=1.3.3
lame_version=3.100
libcdio_version=2.1.0
libcdio_paranoia_version=10.2+2.0.1
libogg_version=1.3.4
libsamplerate_version=0.1.9
libsndfile_version=1.0.28
mac_version=6.11
mp4v2_version=2.0.0
mpg123_version=1.26.4
musepack_version=4.75
opus_version=1.3.1
rnnoise_version=9acc1e5
rubberband_version=1.8.2
speex_version=1.2.0
vorbis_version=1.3.7
wavpack_version=5.4.0

# Package locations
exhale_location=https://gitlab.com/ecodis/exhale/-/archive/v$exhale_version/exhale-v$exhale_version.tar.bz2
faac_location=https://github.com/knik0/faac/archive/${faac_version//./_}.tar.gz
faad2_location=https://github.com/knik0/faad2/archive/${faad2_version//./_}.tar.gz
fdk_aac_location=https://sourceforge.net/projects/opencore-amr/files/fdk-aac/fdk-aac-$fdk_aac_version.tar.gz
ffmpeg_location=https://ffmpeg.org/releases/ffmpeg-$ffmpeg_version.tar.xz
flac_location=https://ftp.osuosl.org/pub/xiph/releases/flac/flac-$flac_version.tar.xz
lame_location=https://sourceforge.net/projects/lame/files/lame/$lame_version/lame-$lame_version.tar.gz
libcdio_location=https://ftp.gnu.org/gnu/libcdio/libcdio-$libcdio_version.tar.bz2
libcdio_paranoia_location=https://ftp.gnu.org/gnu/libcdio/libcdio-paranoia-$libcdio_paranoia_version.tar.bz2
libogg_location=https://ftp.osuosl.org/pub/xiph/releases/ogg/libogg-$libogg_version.tar.xz
libsamplerate_location=http://www.mega-nerd.com/SRC/libsamplerate-$libsamplerate_version.tar.gz
libsndfile_location=http://www.mega-nerd.com/libsndfile/files/libsndfile-$libsndfile_version.tar.gz
mac_location=https://freac.org/patches/MAC_SDK_${mac_version%.*}${mac_version#*.}.zip
mp4v2_location=https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/mp4v2/mp4v2-$mp4v2_version.tar.bz2
mpg123_location=https://mpg123.org/download/mpg123-$mpg123_version.tar.bz2
musepack_location=https://files.musepack.net/source/musepack_src_r${musepack_version%.*}${musepack_version#*.}.tar.gz
opus_location=https://ftp.osuosl.org/pub/xiph/releases/opus/opus-$opus_version.tar.gz
rnnoise_location=https://codeload.github.com/xiph/rnnoise/zip/$rnnoise_version
rubberband_location=https://breakfastquay.com/files/releases/rubberband-$rubberband_version.tar.bz2
speex_location=https://ftp.osuosl.org/pub/xiph/releases/speex/speex-$speex_version.tar.gz
vorbis_location=https://ftp.osuosl.org/pub/xiph/releases/vorbis/libvorbis-$vorbis_version.tar.xz
wavpack_location=http://www.wavpack.com/wavpack-$wavpack_version.tar.bz2

# Patch locations
lame_patches=(https://freac.org/patches/lame-$lame_version-sse-20171014.diff https://freac.org/patches/lame-$lame_version-fastcrc.diff)
lame_patch_levels=(0 1)

lame_patches_ppc=(https://freac.org/patches/lame-$lame_version-altivec-20171014.diff https://freac.org/patches/lame-$lame_version-fastcrc.diff)
lame_patch_levels_ppc=(0 1)

libcdio_patches=(https://freac.org/patches/libcdio-$libcdio_version-cdtext-osx.patch https://freac.org/patches/libcdio-$libcdio_version-cdtext-win32.patch)
libcdio_patch_levels=(1 1)

mac_patches=(https://freac.org/patches/mac-sdk-$mac_version-gcc.patch)
mac_patch_levels=(1)

mp4v2_patches=(https://freac.org/patches/mp4v2-$mp4v2_version-fixes.patch)
mp4v2_patch_levels=(1)

mp4v2_patches_win32=(https://freac.org/patches/mp4v2-$mp4v2_version-fixes.patch https://freac.org/patches/mp4v2-$mp4v2_version-win32.patch)
mp4v2_patch_levels_win32=(1 1)

rubberband_patches=(https://freac.org/patches/rubberband-$rubberband_version-fixed.diff)
rubberband_patch_levels=(1)

vorbis_patches=(https://freac.org/patches/libvorbis-$vorbis_version-aotuv-b6.03.patch https://freac.org/patches/libvorbis-$vorbis_version-aotuv-b6.03-lancer.patch)
vorbis_patch_levels=(1 1)

build () {
  archive=${1##*/}

  if [[ -z $folder ]]; then
    if [[ $archive == *.tar.* ]]; then folder=${archive%.tar.*}; fi
    if [[ $archive == *.zip   ]]; then folder=${archive%.zip}; fi
  fi

  if [[ $1 == *://* ]]; then $DL $archive $1; fi

  rm -fr $folder

  if [[ $archive == *.tar.gz  ]]; then tar xfz $archive; fi
  if [[ $archive == *.tar.bz2 ]]; then tar xfj $archive; fi
  if [[ $archive == *.tar.xz  ]]; then tar xfJ $archive; fi
  if [[ $archive == *.zip     ]]; then unzip   $archive; fi

  cd $folder

  index=0

  for patch in ${patches[@]}; do
    $DL ../${patch##*/} $patch

    if [ ${#patch_levels[index]} -gt 0 ]; then
      $PATCH -E -p${patch_levels[index]} < ../${patch##*/}
    else
      $PATCH -E -p1 < ../${patch##*/}
    fi

    set +e
    let index++
    set -e
  done

  eval $prepare

  if [[ ! -f ./configure ]]; then
    if [[ -f ./configure.in ]] || [[ -f ./configure.ac ]]; then
      autoreconf -i
    fi
  fi

  if [[ -f ./configure ]]; then
    if [[ -z $host_flags && ! -z $host ]]; then
      eval $configure_exports ./configure --host=$host $configure_flags $prefix
    else
      eval $configure_exports ./configure $host_flags $configure_flags $prefix
    fi
  fi
  $MAKE $make_flags -j$jobs

  index=0

  if [[ $uname == *MINGW* ]]; then
    files=($2)
    targets=($3)

    for file in ${files[@]}; do
      strip --strip-all $file
      cp $file ../${targets[index]}

      if [[ ${targets[index]} == *.$sharedext ]]; then
        peflags -d1 -n1 ../${targets[index]}
      else
        peflags -n1 ../${targets[index]}
      fi

      set +e
      let index++
      set -e
    done
  elif [[ -n "$install_script" ]]; then
    $SUDO bash -c "$install_script"
  else
    $SUDO $MAKE $make_flags -j$jobs install
  fi

  cd ..

  unset patches
  unset patch_levels
  unset prepare
  unset configure_exports
  unset configure_flags
  unset host_flags
  unset make_flags
  unset install_script
  unset folder

  export CFLAGS="$cflags $cflags_unroll"
  export LDFLAGS="$ldflags"
}

packages=$@

if [ ${#packages[0]} -eq 0 ]; then
  echo "Usage: build.sh [{list of packages}|all]"
  echo "Available packages: exhale faac faad2 fdk-aac ffmpeg flac lame libcdio libcdio-paranoia libogg libsamplerate libsndfile mac mp4v2 mpg123 musepack opus rnnoise rubberband speex vorbis wavpack"
  echo
elif [ "${packages[0]}" == all ]; then
  if [[ $uname == Darwin ]]; then
    packages=( exhale faad2 fdk-aac ffmpeg flac lame libcdio libcdio-paranoia libogg libsamplerate libsndfile mac mp4v2 mpg123 opus speex vorbis wavpack )
  elif [[ $uname == Haiku ]]; then
    packages=( exhale faac faad2 fdk-aac flac lame libogg mpg123 opus speex vorbis )
  else
    packages=( exhale faac faad2 fdk-aac ffmpeg flac lame libcdio libcdio-paranoia libogg libsamplerate libsndfile mac mp4v2 mpg123 musepack opus rnnoise rubberband speex vorbis wavpack )
  fi
fi

for package in ${packages[@]}; do
  if [ $package == exhale ]; then
    # Build exhale
    if [[ $uname == *MINGW* ]]; then
      prepare="sed -i -e \"s/-fPIC//\" src/makefile.base && sed -i -e \"s/= .(CPP)/= gcc/\" src/makefile.base && sed -i -e \"s/-ldl//\" src/app/makefile && sed -i -e \"s/-l.(PRD_NAME).*/& -lstdc++.static/\" src/app/makefile && sed -i -e \"s/printf_s/printf/\" src/app/exhaleApp.cpp"
    fi
    if [[ $uname == Haiku ]]; then
      make_flags="LIBS="
      install_script="mkdir -p /usr/local/bin && cp bin/exhale /system/non-packaged/bin"
    else
      install_script="mkdir -p /usr/local/bin && cp bin/exhale /usr/local/bin"
    fi
    build $exhale_location bin/exhale.$execext exhale.$execext

  elif [ $package == faac ]; then
    # Build FAAC
    folder=faac-${faac_version//./_}
    prepare="sed -i -e \"s/FAACAPI __stdcall/FAACAPI/\" include/faac.h"
    if [[ $x86_64 != true ]]; then
      if [[ $uname == *MINGW* ]]; then
        configure_exports="WINDRES=\"windres -F pe-i386\""
      fi
    else
      if [[ $uname != FreeBSD ]]; then
        export CFLAGS="$cflags $cflags_unroll -mfpmath=387"
      fi
    fi
    build $faac_location libfaac/.libs/libfaac$sharedinfix.$sharedext FAAC.$sharedext

  elif [ $package == faad2 ]; then
    # Build FAAD2
    folder=faad2-${faad2_version//./_}
    if [[ $uname == *MINGW* ]]; then
      prepare="./utils/win32/ac2ver faad2 configure.ac > libfaad/win32_ver.h"
    elif [[ $uname == Darwin ]]; then
      prepare="sed -i -e \"s/__builtin_bswap16(u16)/((((u16) \\& 0xff) << 8) | ((u16) >> 8))/\" frontend/mp4read.c"
    fi
    build $faad2_location libfaad/.libs/libfaad$sharedinfix.$sharedext FAAD2.$sharedext

  elif [ $package == fdk-aac ]; then
    # Build FDK-AAC
    export CXXFLAGS="$cflags $cflags_unroll"
    build $fdk_aac_location .libs/libfdk-aac$sharedinfix.$sharedext FDK-AAC.$sharedext

  elif [ $package == ffmpeg ]; then
    # Build ffmpeg
    export CFLAGS="$cflags"
    configure_flags="--disable-autodetect --disable-doc --enable-gpl --enable-small --enable-runtime-cpudetect"
    if [[ $arm == true || $arm64 == true ]] && [[ `uname -m` == x86_64 ]]; then
      host_flags="--enable-cross-compile"
      if [[ $arm == true ]]; then
        host_flags="$host_flags --arch=arm"
      else
        host_flags="$host_flags --arch=aarch64"
      fi
      if [[ $uname == Linux ]]; then
        host_flags="$host_flags --target-os=linux"
      fi
    else
      host_flags=" "
    fi
    if [[ $uname == *MINGW* ]]; then
      make_flags="V=1"
    elif [[ $uname == Darwin ]]; then
      configure_flags="$configure_flags --disable-audiotoolbox"
      if [[ $ppc == true ]]; then
        configure_flags="$configure_flags --disable-swscale"
        host_flags="--arch=ppc"
      elif [[ $x86_64 == true ]]; then
        host_flags="--arch=x86_64"
      elif [[ $x86 == true ]]; then
        host_flags="--arch=i386"
      elif [[ $arm64 == true ]]; then
        configure_flags="$configure_flags --enable-cross-compile --disable-asm"
        host_flags="--arch=aarch64"
      fi
    fi
    build $ffmpeg_location ffmpeg.$execext ffmpeg.$execext

  elif [ $package == flac ]; then
    # Build FLAC
    patches=${flac_patches[@]}
    patch_levels=(${flac_patch_levels[@]})
    configure_flags="--disable-cpplibs"
    if [[ $x86_64 == true ]] || [[ $arm64 == true ]]; then
      if [[ $uname == *MINGW* ]]; then
        prepare="sed -i -e \"s/#undef FLAC__CPU_IA32//\" config.h.in && sed -i -e \"s/#undef FLAC__CPU_X86_64/#define FLAC__CPU_X86_64 1/\" config.h.in && sed -i -e \"s/ARCH_SUBDIRS = ia32/ARCH_SUBDIRS =/\" src/libFLAC/Makefile.in && sed -i -e \"s/LOCAL_EXTRA_LIBADD = ia32\/libFLAC-asm\.la/LOCAL_EXTRA_LIBADD =/\" src/libFLAC/Makefile.in"
      fi
      configure_flags="$configure_flags --enable-64-bit-words"
    fi
    if [[ $uname == Darwin ]]; then
      configure_flags="$configure_flags --disable-asm-optimizations"
    fi
    build $flac_location src/libFLAC/.libs/libFLAC$sharedinfix.$sharedext FLAC.$sharedext
    if [[ $uname == *MINGW* ]]; then
      sed -i -b -e "s/libogg-0.dll/Ogg.dll\x00\x00\x00\x00\x00/" FLAC.$sharedext
    fi

  elif [ $package == lame ]; then
    # Build LAME
    if [[ $ppc == true ]]; then
      patches=${lame_patches_ppc[@]}
      patch_levels=(${lame_patch_levels_ppc[@]})
    elif [[ $x86 == true ]] || [[ $x86_64 == true ]]; then
      patches=${lame_patches[@]}
      patch_levels=(${lame_patch_levels[@]})
    fi
    if [[ $uname == *MINGW* ]]; then
      prepare="sed -i -e \"/lame_init_old/d\" include/libmp3lame.sym"
    elif [[ $uname == Darwin ]]; then
      prepare="sed -i -e \"/lame_init_old/d\" include/libmp3lame.sym && sed -i -e \"s/strnlen(\\(.*\\),[^)]*)/strlen(\1)/\" frontend/parse.c"
    fi
    if [[ $ppc == true ]]; then
        export CFLAGS="$cflags $cflags_unroll -faltivec -DALTIVEC"
    elif [[ $x86 == true ]]; then
      if [[ $uname == *MINGW* ]] || [[ $uname == FreeBSD ]] || [[ $uname == Darwin ]]; then
        export CFLAGS="$cflags $cflags_unroll -mfpmath=sse"
      fi

      configure_flags="--enable-nasm"
    fi
    build $lame_location libmp3lame/.libs/libmp3lame$sharedinfix.$sharedext LAME.$sharedext

  elif [ $package == libcdio ]; then
    # Build libcdio
    patches=${libcdio_patches[@]}
    patch_levels=(${libcdio_patch_levels[@]})
    export CFLAGS="$cflags -Os"
    configure_flags="--disable-cxx"
    build $libcdio_location lib/driver/.libs/libcdio$sharedinfix.$sharedext libcdio.$sharedext

  elif [ $package == libcdio-paranoia ]; then
    # Build libcdio-paranoia
    export CFLAGS="$cflags -Os"
    if [[ $uname == Darwin ]]; then
      prepare="sed -i -e \"s/-Wl,--version-script=.*\\.la\\.ver//\" lib/*/Makefile.in"
    fi
    if [[ $uname != FreeBSD ]]; then
      configure_exports="LIBCDIO_CFLAGS=\"-I.\" LIBCDIO_LIBS=\"-lcdio\""
    else
      configure_exports="LIBCDIO_CFLAGS=\"-I/usr/local/include\" LIBCDIO_LIBS=\"-L/usr/local/lib -lcdio\""
    fi
    build $libcdio_paranoia_location "lib/cdda_interface/.libs/libcdio_cdda$sharedinfix.$sharedext lib/paranoia/.libs/libcdio_paranoia$sharedinfix.$sharedext" "libcdio_cdda.$sharedext libcdio_paranoia.$sharedext"

  elif [ $package == libogg ]; then
    # Build Ogg
    build $libogg_location src/.libs/libogg$sharedinfix.$sharedext Ogg.$sharedext

  elif [ $package == libsamplerate ]; then
    # Build libsamplerate
    prepare="$DL Cfg/config.guess 'https://raw.githubusercontent.com/gcc-mirror/gcc/17bc331/config.guess'; $DL Cfg/config.sub 'https://raw.githubusercontent.com/gcc-mirror/gcc/17bc331/config.sub'"
    if [[ $uname == Darwin ]]; then
      prepare="$prepare; sed -i -e \"s/typedef struct AUDIO_OUT_s/struct AUDIO_OUT_s/\" examples/audio_out.c && sed -i -e \"s/} AUDIO_OUT ;/} AUDIO_OUT_s ;/\" examples/audio_out.c"
    elif [[ $uname != FreeBSD ]] && [[ $x86_64 == true ]]; then
      export CFLAGS="$cflags $cflags_unroll -mfpmath=387"
    fi
    build $libsamplerate_location src/.libs/libsamplerate$sharedinfix.$sharedext SampleRate.$sharedext

  elif [ $package == libsndfile ]; then
    # Build libsndfile
    if [[ $uname == Darwin ]]; then
      prepare="sed -i -e \"s/ -Wvla//\" configure"
    elif [[ $uname == *MINGW* ]] && [[ $x86 == true ]]; then
      configure_exports="RC=\"windres -F pe-i386\""
    fi
    configure_flags="--disable-external-libs"
    build $libsndfile_location src/.libs/libsndfile$sharedinfix.$sharedext SndFile.$sharedext

  elif [ $package == mac ]; then
    # Build Monkey's Audio
    archive=${mac_location##*/}
    folder=${archive%.zip}
    $DL $archive $mac_location
    rm -fr $folder; unzip -d $folder $archive
    rm $archive; zip -m -r $archive $folder
    export CXXFLAGS="$cflags $cflags_unroll"
    patches=${mac_patches[@]}
    patch_levels=(${mac_patch_levels[@]})
    prepare="chmod 777 configure"
    build $archive Source/MACDll.$sharedext MACDll.$sharedext

  elif [ $package == mp4v2 ]; then
    # Build mp4v2
    configure_flags="--disable-gch"
    export CXXFLAGS="$cflags -Os"
    export LDFLAGS="$ldflags -lm -lstdc++"
    if [[ $uname == *MINGW* ]]; then
      patches=${mp4v2_patches_win32[@]}
      patch_levels=(${mp4v2_patch_levels_win32[@]})
    else
      patches=${mp4v2_patches[@]}
      patch_levels=(${mp4v2_patch_levels[@]})
    fi
    prepare="$DL autoaux/config.guess 'https://raw.githubusercontent.com/gcc-mirror/gcc/17bc331/config.guess'; $DL autoaux/config.sub 'https://raw.githubusercontent.com/gcc-mirror/gcc/17bc331/config.sub'"
    build $mp4v2_location src/libmp4v2$sharedinfix.$sharedext MP4v2.$sharedext

  elif [ $package == mpg123 ]; then
    # Build mpg123
    configure_flags="--enable-modules=no"
    if [[ $ppc == true ]]; then
      configure_flags="$configure_flags --with-cpu=altivec"
    elif [[ $x86_64 == true ]]; then
      if [[ $uname == Darwin ]]; then
        configure_flags="$configure_flags --with-cpu=x86-64_alone"
      else
        configure_flags="$configure_flags --with-cpu=x86-64"
      fi
    elif [[ $x86 == true ]]; then
      configure_flags="$configure_flags --with-cpu=sse"
    elif [[ $arm == true ]]; then
      configure_flags="$configure_flags --with-cpu=neon"
    elif [[ $arm64 == true ]]; then
      configure_flags="$configure_flags --with-cpu=neon64"
    fi
    build $mpg123_location src/libmpg123/.libs/libmpg123$sharedinfix.$sharedext mpg123.$sharedext

  elif [ $package == musepack ]; then
    # Build MusePack
    prepare="touch include/config.h.in; head -n 34 configure.in >> configure.ac; echo \"AM_CONDITIONAL([HAVE_VISIBILITY], [false])\" >> configure.ac; echo \"AC_CHECK_LIB([m],[cos])\" >> configure.ac; tail -n 18 configure.in >> configure.ac; rm configure.in"
    configure_flags="--disable-shared"
    build $musepack_location "mpcenc/mpcenc.$execext mpcdec/mpcdec.$execext" "mpcenc.$execext mpcdec.$execext"

  elif [ $package == opus ]; then
    # Build Opus
    if [[ $x86 == true ]]; then
      export CFLAGS="$cflags $cflags_unroll -mfpmath=sse"
    fi
    configure_flags="--enable-float-approx"
    if [[ $uname == Darwin ]] && [[ $x86_64 != true ]]; then
      configure_flags="$configure_flags --disable-intrinsics"
    fi
    build $opus_location .libs/libopus$sharedinfix.$sharedext Opus.$sharedext

  elif [ $package == rnnoise ]; then
    # Build RNNoise
    archive=rnnoise-${rnnoise_location##*/}.zip
    $DL $archive $rnnoise_location
    zip -d $archive rnnoise-$rnnoise_version/TRAINING
    build $archive .libs/librnnoise$sharedinfix.$sharedext RNNoise.$sharedext

  elif [ $package == rubberband ]; then
    # Build RubberBand
    export CXXFLAGS="$cflags $cflags_unroll"
    patches=${rubberband_patches[@]}
    patch_levels=(${rubberband_patch_levels[@]})
    configure_exports="FFTW_CFLAGS=\" \" FFTW_LIBS=\" \" SRC_CFLAGS=\" \" SRC_LIBS=\" \" Vamp_CFLAGS=\" \" Vamp_LIBS=\" \""
    if [[ $uname == *MINGW* ]]; then
      prepare="sed -i -e \"s/-DNO_THREAD_CHECKS -DUSE_PTHREADS/-DUSE_OWN_ALIGNED_MALLOC/\" Makefile.in && sed -i -e \"s/-lpthread//\" Makefile.in && sed -i -e \"s/all:.*/all: bin lib \$\(DYNAMIC_TARGET\)/\" Makefile.in && sed -i -e \"s/:= .so/:= .dll/\" Makefile.in"
      configure_exports="$configure_exports SNDFILE_CFLAGS=\" \" SNDFILE_LIBS=\" \""
    elif [[ $uname == Darwin ]]; then
      prepare="sed -i -e \"s/-Wl,-Bsymbolic//\" Makefile.in && sed -i -e \"s/ -Wl,-soname=.*//\" Makefile.in && sed -i -e \"s/:= .so/:= .dylib/\" Makefile.in"
      configure_exports="$configure_exports SNDFILE_CFLAGS=\" \" SNDFILE_LIBS=\"-lsndfile\""
    else
      configure_exports="$configure_exports SNDFILE_CFLAGS=\" \" SNDFILE_LIBS=\"-lsndfile\""
    fi
    build $rubberband_location lib/librubberband.$sharedext RubberBand.$sharedext

  elif [ $package == speex ]; then
    # Build Speex
    if [[ $x86 == true ]]; then
      export CFLAGS="$cflags $cflags_unroll -mfpmath=sse"
    fi
    build $speex_location libspeex/.libs/libspeex$sharedinfix.$sharedext Speex.$sharedext

  elif [ $package == vorbis ]; then
    # Build Vorbis
    patches=${vorbis_patches[@]}
    patch_levels=(${vorbis_patch_levels[@]})
    if [[ $x86 != true ]]; then
      export CFLAGS="$cflags"
    else
      if [[ $uname == Darwin ]]; then
        export CFLAGS="$cflags -mno-sse"
      else
        export CFLAGS="$cflags -mfpmath=sse"
      fi
    fi
    build $vorbis_location "lib/.libs/libvorbis$sharedinfix.$sharedext lib/.libs/libvorbisenc$sharedinfix.$sharedext" "Vorbis.$sharedext VorbisEnc.$sharedext"
    if [[ $uname == *MINGW* ]]; then
      sed -i -b -e "s/libogg-0.dll/Ogg.dll\x00\x00\x00\x00\x00/" Vorbis.$sharedext

      sed -i -b -e "s/libogg-0.dll/Ogg.dll\x00\x00\x00\x00\x00/" VorbisEnc.$sharedext
      sed -i -b -e "s/libvorbis-0.dll/Vorbis.dll\x00\x00\x00\x00\x00/" VorbisEnc.$sharedext
    fi

  elif [ $package == wavpack ]; then
    # Build WavPack
    configure_flags="--disable-shared"
    if [[ $uname == *MINGW* ]]; then
      prepare="sed -i -e \"s/#ifndef LIBWAVPACK_VERSION_STRING/#ifndef LIBWAVPACK_VERSION_STRING2/\" src/common_utils.c"
      configure_flags="$configure_flags --disable-asm"
    elif [[ $uname == Darwin ]]; then
      configure_flags="$configure_flags --disable-asm"
    fi
    build $wavpack_location "cli/wavpack.$execext cli/wvunpack.$execext" "wavpack.$execext wvunpack.$execext"
  fi
done
