Skip to content

Commit

Permalink
Added FreeSurround to Externals
Browse files Browse the repository at this point in the history
Also cleaned up its source code to support only 5.1 and 7.1 setups.
  • Loading branch information
LAGonauta committed Feb 14, 2019
1 parent 950b952 commit 7b93758
Show file tree
Hide file tree
Showing 15 changed files with 2,834 additions and 0 deletions.
5 changes: 5 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -587,6 +587,11 @@ else()
set(PNG png)
endif()

# Using static FreeSurround from Externals
# There is no system FreeSurround library.
message(STATUS "Using static FreeSurround from Externals")
add_subdirectory(Externals/FreeSurround)

if (APPLE)
message(STATUS "Using ed25519 from Externals")
add_subdirectory(Externals/ed25519)
Expand Down
14 changes: 14 additions & 0 deletions Externals/FreeSurround/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

set(SRCS
source/ChannelMaps.cpp
source/KissFFT.cpp
source/KissFFTR.cpp
source/FreeSurroundDecoder.cpp
)

add_library(FreeSurround STATIC ${SRCS})
target_include_directories(FreeSurround PUBLIC include)
target_compile_options(FreeSurround PRIVATE -w)
53 changes: 53 additions & 0 deletions Externals/FreeSurround/FreeSurround.vcxproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{8498F2FA-5CA6-4169-9971-DE5B1FE6132C}</ProjectGuid>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\Source\VSProps\Base.props" />
<Import Project="..\..\Source\VSProps\ClDisableAllWarnings.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<ItemGroup>
<ClInclude Include="include\FreeSurround\ChannelMaps.h" />
<ClInclude Include="include\FreeSurround\FreeSurroundDecoder.h" />
<ClInclude Include="include\FreeSurround\KissFFT.h" />
<ClInclude Include="include\FreeSurround\KissFFTR.h" />
<ClInclude Include="include\FreeSurround\_KissFFTGuts.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="source\ChannelMaps.cpp" />
<ClCompile Include="source\FreeSurroundDecoder.cpp" />
<ClCompile Include="source\KissFFT.cpp" />
<ClCompile Include="source\KissFFTR.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
42 changes: 42 additions & 0 deletions Externals/FreeSurround/FreeSurround.vcxproj.filters
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="source\ChannelMaps.cpp">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="source\FreeSurroundDecoder.cpp">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="source\KissFFT.cpp">
<Filter>source</Filter>
</ClCompile>
<ClCompile Include="source\KissFFTR.cpp">
<Filter>source</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="include\FreeSurround\_KissFFTGuts.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="include\FreeSurround\ChannelMaps.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="include\FreeSurround\FreeSurroundDecoder.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="include\FreeSurround\KissFFT.h">
<Filter>include</Filter>
</ClInclude>
<ClInclude Include="include\FreeSurround\KissFFTR.h">
<Filter>include</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="include">
<UniqueIdentifier>{776ecb31-6d5e-489f-bac9-b91a1b202345}</UniqueIdentifier>
</Filter>
<Filter Include="source">
<UniqueIdentifier>{11345325-d67c-4a21-b2e9-c7c6c8cfc8b4}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>
36 changes: 36 additions & 0 deletions Externals/FreeSurround/include/FreeSurround/ChannelMaps.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
Copyright (C) 2010 Christian Kothe
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

#ifndef CHANNELMAPS_H
#define CHANNELMAPS_H
#include "FreeSurroundDecoder.h"
#include <map>
#include <vector>

const int grid_res = 21; // resolution of the lookup grid

// channel allocation maps (per setup)
typedef std::vector<std::vector<float *>> alloc_lut;
extern std::map<unsigned, alloc_lut> chn_alloc;
// channel metadata maps (per setup)
extern std::map<unsigned, std::vector<float>> chn_angle;
extern std::map<unsigned, std::vector<float>> chn_xsf;
extern std::map<unsigned, std::vector<float>> chn_ysf;
extern std::map<unsigned, std::vector<channel_id>> chn_id;

#endif
209 changes: 209 additions & 0 deletions Externals/FreeSurround/include/FreeSurround/FreeSurroundDecoder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
// Copyright (C) 2007-2010 Christian Kothe
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
// USA.

#ifndef FREESURROUND_DECODER_H
#define FREESURROUND_DECODER_H
#include "KissFFTR.h"
#include <complex>
#include <vector>

typedef std::complex<double> cplx;

// Identifiers for the supported output channels (from front to back, left to
// right). The ordering here also determines the ordering of interleaved
// samples in the output signal.

typedef enum channel_id {
ci_none = 0,
ci_front_left = 1 << 1,
ci_front_center_left = 1 << 2,
ci_front_center = 1 << 3,
ci_front_center_right = 1 << 4,
ci_front_right = 1 << 5,
ci_side_front_left = 1 << 6,
ci_side_front_right = 1 << 7,
ci_side_center_left = 1 << 8,
ci_side_center_right = 1 << 9,
ci_side_back_left = 1 << 10,
ci_side_back_right = 1 << 11,
ci_back_left = 1 << 12,
ci_back_center_left = 1 << 13,
ci_back_center = 1 << 14,
ci_back_center_right = 1 << 15,
ci_back_right = 1 << 16,
ci_lfe = 1 << 31
} channel_id;

// The supported output channel setups. A channel setup is defined by the set
// of channels that are present. Here is a graphic of the cs_5point1 setup:
// http://en.wikipedia.org/wiki/File:5_1_channels_(surround_sound)_label.svg
typedef enum channel_setup {
cs_5point1 = ci_front_left | ci_front_center | ci_front_right | ci_back_left |
ci_back_right | ci_lfe,

cs_7point1 = ci_front_left | ci_front_center | ci_front_right |
ci_side_center_left | ci_side_center_right | ci_back_left |
ci_back_right | ci_lfe
} channel_setup;

// The FreeSurround decoder.

class DPL2FSDecoder {
public:
// Create an instance of the decoder.
// @param setup The output channel setup -- determines the number of output
// channels and their place in the sound field.
// @param blocksize Granularity at which data is processed by the decode()
// function. Must be a power of two and should correspond to ca. 10ms worth
// of single-channel samples (default is 4096 for 44.1Khz data). Do not make
// it shorter or longer than 5ms to 20ms since the granularity at which
// locations are decoded changes with this.
DPL2FSDecoder();
~DPL2FSDecoder();

void Init(channel_setup setup = cs_5point1, unsigned int blocksize = 4096,
unsigned int samplerate = 48000);

// Decode a chunk of stereo sound. The output is delayed by half of the
// blocksize. This function is the only one needed for straightforward
// decoding.
// @param input Contains exactly blocksize (multiplexed) stereo samples, i.e.
// 2*blocksize numbers.
// @return A pointer to an internal buffer of exactly blocksize (multiplexed)
// multichannel samples. The actual number of values depends on the number of
// output channels in the chosen channel setup.
float *decode(float *input);

// Flush the internal buffer.
void flush();

// set soundfield & rendering parameters
// for more information, see full FreeSurround source code
void set_circular_wrap(float v);
void set_shift(float v);
void set_depth(float v);
void set_focus(float v);
void set_center_image(float v);
void set_front_separation(float v);
void set_rear_separation(float v);
void set_low_cutoff(float v);
void set_high_cutoff(float v);
void set_bass_redirection(bool v);

// number of samples currently held in the buffer
unsigned int buffered();

private:
// constants
const float pi = 3.141592654f;
const float epsilon = 0.000001f;

// number of samples per input/output block, number of output channels
unsigned int N, C;
unsigned int samplerate;

// the channel setup
channel_setup setup;
bool initialized;

// parameters
// angle of the front soundstage around the listener (90\B0=default)
float circular_wrap;

// forward/backward offset of the soundstage
float shift;

// backward extension of the soundstage
float depth;

// localization of the sound events
float focus;

// presence of the center speaker
float center_image;

// front stereo separation
float front_separation;

// rear stereo separation
float rear_separation;

// LFE cutoff frequencies
float lo_cut, hi_cut;

// whether to use the LFE channel
bool use_lfe;

// FFT data structures
// left total, right total (source arrays), time-domain destination buffer
// array
std::vector<double> lt, rt, dst;

// left total / right total in frequency domain
std::vector<cplx> lf, rf;

// FFT buffers
kiss_fftr_cfg forward, inverse;

// buffers
// whether the buffer is currently empty or dirty
bool buffer_empty;

// stereo input buffer (multiplexed)
std::vector<float> inbuf;

// multichannel output buffer (multiplexed)
std::vector<float> outbuf;

// the window function, precomputed
std::vector<double> wnd;

// the signal to be constructed in every channel, in the frequency domain
// instantiate the decoder with a given channel setup and processing block
// size (in samples)
std::vector<std::vector<cplx>> signal;

// helper functions
inline float sqr(double x);
inline double amplitude(const cplx &x);
inline double phase(const cplx &x);
inline cplx polar(double a, double p);
inline float min(double a, double b);
inline float max(double a, double b);
inline float clamp(double x);
inline float sign(double x);

// get the distance of the soundfield edge, along a given angle
inline double edgedistance(double a);

// get the index (and fractional offset!) in a piecewise-linear channel
// allocation grid
int map_to_grid(double &x);

// decode a block of data and overlap-add it into outbuf
void buffered_decode(float *input);

// transform amp/phase difference space into x/y soundfield space
void transform_decode(double a, double p, double &x, double &y);

// apply a circular_wrap transformation to some position
void transform_circular_wrap(double &x, double &y, double refangle);

// apply a focus transformation to some position
void transform_focus(double &x, double &y, double focus);
};
#endif
Loading

0 comments on commit 7b93758

Please sign in to comment.