surroundize

Tool/PipeWire filter to convert stereo audio to surround
git clone https://git.neptards.moe/u3shit/surroundize.git
Log | Files | Refs | README | LICENSE

freesurround_decoder.h (8779B)


      1 /*
      2 Copyright (C) 2007-2010 Christian Kothe
      3 
      4 This program is free software; you can redistribute it and/or
      5 modify it under the terms of the GNU General Public License
      6 as published by the Free Software Foundation; either version 2
      7 of the License, or (at your option) any later version.
      8 
      9 This program is distributed in the hope that it will be useful,
     10 but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 GNU General Public License for more details.
     13 
     14 You should have received a copy of the GNU General Public License
     15 along with this program; if not, write to the Free Software
     16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
     17 */
     18 
     19 #ifndef FREESURROUND_DECODER_H
     20 #define FREESURROUND_DECODER_H
     21 
     22 #include <utility>
     23 
     24 /**
     25 * Identifiers for the supported output channels (from front to back, left to right).
     26 * The ordering here also determines the ordering of interleaved samples in the output signal.
     27 */
     28 enum channel_id {
     29 	ci_none					= 0,
     30 	ci_front_left			= 1<<1,
     31 	ci_front_center_left	= 1<<2,
     32 	ci_front_center			= 1<<3,
     33 	ci_front_center_right	= 1<<4,
     34 	ci_front_right			= 1<<5,
     35 	ci_side_front_left		= 1<<6,
     36 	ci_side_front_right		= 1<<7,
     37 	ci_side_center_left		= 1<<8,
     38 	ci_side_center_right	= 1<<9,
     39 	ci_side_back_left		= 1<<10,
     40 	ci_side_back_right		= 1<<11,
     41 	ci_back_left			= 1<<12,
     42 	ci_back_center_left		= 1<<13,
     43 	ci_back_center			= 1<<14,
     44 	ci_back_center_right	= 1<<15,
     45 	ci_back_right			= 1<<16,
     46 	ci_lfe					= 1<<31
     47 };
     48 
     49 /**
     50 * The supported output channel setups.
     51 * A channel setup is defined by the set of channels that are present. Here is a graphic
     52 * of the cs_5point1 setup: http://en.wikipedia.org/wiki/File:5_1_channels_(surround_sound)_label.svg
     53 */
     54 enum channel_setup {
     55 	cs_stereo = ci_front_left | ci_front_right | ci_lfe,
     56 	cs_3stereo = ci_front_left | ci_front_center | ci_front_right | ci_lfe,
     57 	cs_5stereo = ci_front_left | ci_front_center_left | ci_front_center | ci_front_center_right | ci_front_right | ci_lfe,
     58 	cs_4point1 = ci_front_left | ci_front_right | ci_back_left | ci_back_right | ci_lfe,
     59 	cs_5point1 = ci_front_left | ci_front_center | ci_front_right | ci_back_left | ci_back_right | ci_lfe,
     60 	cs_6point1 = ci_front_left | ci_front_center | ci_front_right | ci_side_center_left | ci_side_center_right | ci_back_center | ci_lfe,
     61 	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,
     62 	cs_7point1_panorama = ci_front_left | ci_front_center_left | ci_front_center | ci_front_center_right | ci_front_right |
     63 						  ci_side_center_left | ci_side_center_right | ci_lfe,
     64 	cs_7point1_tricenter = ci_front_left | ci_front_center_left | ci_front_center | ci_front_center_right | ci_front_right |
     65 						   ci_back_left | ci_back_right | ci_lfe,
     66 	cs_8point1 = ci_front_left | ci_front_center | ci_front_right | ci_side_center_left | ci_side_center_right |
     67 				 ci_back_left | ci_back_center | ci_back_right | ci_lfe,
     68 	cs_9point1_densepanorama = ci_front_left | ci_front_center_left | ci_front_center | ci_front_center_right | ci_front_right |
     69 							   ci_side_front_left | ci_side_front_right | ci_side_center_left | ci_side_center_right | ci_lfe,
     70 	cs_9point1_wrap = ci_front_left | ci_front_center_left | ci_front_center | ci_front_center_right | ci_front_right |
     71 					  ci_side_center_left | ci_side_center_right | ci_back_left | ci_back_right | ci_lfe,
     72 	cs_11point1_densewrap = ci_front_left | ci_front_center_left | ci_front_center | ci_front_center_right | ci_front_right |
     73 					       ci_side_front_left | ci_side_front_right | ci_side_center_left | ci_side_center_right |
     74 						   ci_side_back_left | ci_side_back_right | ci_lfe,
     75 	cs_13point1_totalwrap = ci_front_left | ci_front_center_left | ci_front_center | ci_front_center_right | ci_front_right |
     76 					       ci_side_front_left | ci_side_front_right | ci_side_center_left | ci_side_center_right |
     77 						   ci_side_back_left | ci_side_back_right | ci_back_left | ci_back_right | ci_lfe,
     78 	cs_16point1 = ci_front_left | ci_front_center_left | ci_front_center | ci_front_center_right | ci_front_right |
     79 			      ci_side_front_left | ci_side_front_right | ci_side_center_left | ci_side_center_right | ci_side_back_left |
     80 				  ci_side_back_right | ci_back_left | ci_back_center_left | ci_back_center | ci_back_center_right | ci_back_right | ci_lfe,
     81 	cs_legacy = 0 // same channels as cs_5point1 but different upmixing transform; does not support the focus control
     82 };
     83 
     84 
     85 /**
     86 * The FreeSurround decoder.
     87 */
     88 class freesurround_decoder {
     89 public:
     90 
     91 	/**
     92 	* Create an instance of the decoder.
     93 	* @param setup The output channel setup -- determines the number of output channels
     94 	*			   and their place in the sound field.
     95     * U3 NOTE: 4096@44.1kHz is 92.9ms...
     96 	* @param blocksize Granularity at which data is processed by the decode() function.
     97 	*				   Must be a power of two and should correspond to ca. 10ms worth of single-channel
     98 	*				   samples (default is 4096 for 44.1Khz data). Do not make it shorter or longer
     99 	*				   than 5ms to 20ms since the granularity at which locations are decoded
    100 	*				   changes with this.
    101 	*/
    102 	freesurround_decoder(channel_setup setup=cs_5point1, unsigned blocksize=4096);
    103 	~freesurround_decoder();
    104 
    105     freesurround_decoder(freesurround_decoder&& o) noexcept : impl{std::exchange(o.impl, nullptr)} {}
    106     freesurround_decoder& operator=(freesurround_decoder o) noexcept
    107     {
    108       std::swap(impl, o.impl);
    109       return *this;
    110     }
    111 
    112 	/**
    113 	* Decode a chunk of stereo sound. The output is delayed by half of the blocksize.
    114 	* This function is the only one needed for straightforward decoding.
    115 	* @param input Contains exactly blocksize (multiplexed) stereo samples, i.e. 2*blocksize numbers.
    116 	* @return A pointer to an internal buffer of exactly blocksize (multiplexed) multichannel samples.
    117 	*		  The actual number of values depends on the number of output channels in the chosen
    118 	*		  channel setup.
    119 	*/
    120 	const float* decode(const float* input);
    121 
    122 	/**
    123 	* Flush the internal buffer.
    124 	*/
    125 	void flush();
    126 
    127 
    128 	// --- soundfield transformations
    129 	// These functions allow to set up geometric transformations of the sound field after it has been decoded.
    130 	// The sound field is best pictured as a 2-dimensional square with the listener in its
    131 	// center which can be shifted or stretched in various ways before it is sent to the
    132 	// speakers. The order in which these transformations are applied is as listed below.
    133 
    134 	/**
    135 	* Allows to wrap the soundfield around the listener in a circular manner.
    136 	* Determines the angle of the frontal sound stage relative to the listener, in degrees.
    137 	* A setting of 90° corresponds to standard surround decoding, 180° stretches the front stage from
    138 	* ear to ear, 270° wraps it around most of the head. The side and rear content of the sound
    139 	* field is compressed accordingly behind the listerer. (default: 90, range: [0°..360°])
    140 	*/
    141 	void circular_wrap(float v);
    142 
    143 	/**
    144 	* Allows to shift the soundfield forward or backward.
    145 	* Value range: [-1.0..+1.0]. 0 is no offset, positive values move the sound
    146 	* forward, negative values move it backwards. (default: 0)
    147 	*/
    148 	void shift(float v);
    149 
    150 	/**
    151 	* Allows to scale the soundfield backwards.
    152 	* Value range: [0.0..+5.0] -- 0 is all compressed to the front, 1 is no change, 5 is scaled 5x backwards (default: 1)
    153 	*/
    154 	void depth(float v);
    155 
    156 	/**
    157 	* Allows to control the localization (i.e., focality) of sources.
    158 	* Value range: [-1.0..+1.0] -- 0 means unchanged, positive means more localized, negative means more ambient (default: 0)
    159 	*/
    160 	void focus(float v);
    161 
    162 
    163 	// --- rendering parameters
    164 	// These parameters control how the sound field is mapped onto speakers.
    165 
    166 	/**
    167 	* Set the front stereo separation.
    168 	* Value range: [0.0..inf] -- 1.0 is default, 0.0 is mono.
    169 	*/
    170 	void front_separation(float v);
    171 
    172 	/**
    173 	* Set the rear stereo separation.
    174 	* Value range: [0.0..inf] -- 1.0 is default, 0.0 is mono.
    175 	*/
    176 	void rear_separation(float v);
    177 
    178 
    179 	// --- bass redirection (to LFE)
    180 
    181 	/**
    182 	* Enable/disable LFE channel (default: false = disabled)
    183 	*/
    184 	void bass_redirection(bool v);
    185 
    186 	/**
    187 	* Set the lower end of the transition band, in Hz/Nyquist (default: 40/22050).
    188 	*/
    189 	void low_cutoff(float v);
    190 
    191 	/**
    192 	* Set the upper end of the transition band, in Hz/Nyquist (default: 90/22050).
    193 	*/
    194 	void high_cutoff(float v);
    195 
    196 
    197 	// --- info
    198 
    199 	/**
    200 	* Number of samples currently held in the buffer.
    201 	*/
    202 	unsigned buffered();
    203 
    204 	/**
    205 	* Number of channels in the given setup.
    206 	*/
    207 	static unsigned num_channels(channel_setup s);
    208 
    209 	/**
    210 	* Channel id of the i'th channel in the given setup.
    211 	*/
    212 	static channel_id channel_at(channel_setup s, unsigned i);
    213 
    214 private:
    215 	class decoder_impl *impl; // private implementation
    216 };
    217 
    218 #endif