Skip to content
Permalink
Browse files

Documentation files

  • Loading branch information
dlevin256 committed Dec 2, 2019
1 parent c9c1887 commit 7998955b98415bb1be08162057be18cde93347ea
Showing with 131,188 additions and 3 deletions.
  1. +1 −3 .gitignore
  2. +66 −0 docs/cxxdox.yml
  3. +3 −0 docs/docs/bq.md
  4. +123 −0 docs/docs/bq_gallery.md
  5. +70 −0 docs/docs/conversion.md
  6. +45 −0 docs/docs/convert_stereo.md
  7. +70 −0 docs/docs/convolution.md
  8. +11 −0 docs/docs/css/fix.css
  9. +149 −0 docs/docs/dft.md
  10. +33 −0 docs/docs/dft2.md
  11. +20 −0 docs/docs/dft_format.md
  12. +2 −0 docs/docs/ebur128.md
  13. +42 −0 docs/docs/expressions.md
  14. +12 −0 docs/docs/file_support.md
  15. +88 −0 docs/docs/fir.md
  16. +147 −0 docs/docs/fir_gallery.md
  17. +722 −0 docs/docs/img/audio_draft_quality.svg
  18. +722 −0 docs/docs/img/audio_high_quality.svg
  19. +722 −0 docs/docs/img/audio_low_quality.svg
  20. +722 −0 docs/docs/img/audio_normal_quality.svg
  21. +2,017 −0 docs/docs/img/biquad_bandpass.svg
  22. +2,163 −0 docs/docs/img/biquad_custom_filter_lowpass.svg
  23. +2,170 −0 docs/docs/img/biquad_filter_lowpass.svg
  24. +2,116 −0 docs/docs/img/biquad_highpass.svg
  25. +2,005 −0 docs/docs/img/biquad_highshelf.svg
  26. +2,084 −0 docs/docs/img/biquad_lowpass.svg
  27. +1,989 −0 docs/docs/img/biquad_lowshelf.svg
  28. +2,338 −0 docs/docs/img/biquad_notch.svg
  29. +2,028 −0 docs/docs/img/biquad_peak.svg
  30. +2,148 −0 docs/docs/img/biquad_peak2.svg
  31. +12,057 −0 docs/docs/img/filtered_noise.svg
  32. +13,617 −0 docs/docs/img/filtered_noise2.svg
  33. +13,649 −0 docs/docs/img/filtered_noise3.svg
  34. +2,672 −0 docs/docs/img/fir_bandpass_kaiser.svg
  35. +2,503 −0 docs/docs/img/fir_bandstop_kaiser.svg
  36. +2,462 −0 docs/docs/img/fir_highpass_kaiser.svg
  37. +12,481 −0 docs/docs/img/fir_lowpass_blackman.svg
  38. +2,238 −0 docs/docs/img/fir_lowpass_hann.svg
  39. +2,543 −0 docs/docs/img/fir_lowpass_kaiser.svg
  40. +13,364 −0 docs/docs/img/noise.svg
  41. +2,174 −0 docs/docs/img/window_bartlett.svg
  42. +2,197 −0 docs/docs/img/window_bartlett_hann.svg
  43. +2,194 −0 docs/docs/img/window_blackman.svg
  44. +2,206 −0 docs/docs/img/window_blackman_harris.svg
  45. +2,209 −0 docs/docs/img/window_bohman.svg
  46. +2,174 −0 docs/docs/img/window_cosine.svg
  47. +2,115 −0 docs/docs/img/window_flattop.svg
  48. +2,104 −0 docs/docs/img/window_gaussian.svg
  49. +2,175 −0 docs/docs/img/window_hamming.svg
  50. +2,200 −0 docs/docs/img/window_hann.svg
  51. +2,213 −0 docs/docs/img/window_kaiser.svg
  52. +2,161 −0 docs/docs/img/window_lanczos.svg
  53. +2,201 −0 docs/docs/img/window_triangular.svg
  54. +50 −0 docs/docs/index.md
  55. +66 −0 docs/docs/js/math.js
  56. +48 −0 docs/docs/normalize.md
  57. +20 −0 docs/docs/plot.md
  58. +52 −0 docs/docs/read_audio.md
  59. +4 −0 docs/docs/src.md
  60. +18 −0 docs/docs/src_gallery.md
  61. +81 −0 docs/docs/types.md
  62. +112 −0 docs/mkdocs.yml
@@ -76,10 +76,8 @@ var/
*.egg
venv/


# Documentation
docs/
mkdocs/
docs/update.sh

# CLion
.idea/
@@ -0,0 +1,66 @@
title: KFR

postprocessor:
ignore:
- CMT_INLINE
- KFR_SINTRIN
- KFR_INTRIN
- KFR_INTRINSIC
- KFR_SINTRINSIC
- KFR_FUNC
- KFR_FUNCTION
- CMT_INTRIN
- CMT_UNUSED

clang:
arguments:
- '-DKFR_ENABLE_FLAC=1'
- '-DCMT_FORCE_GENERIC_CPU=1'

input_directory: ../include/kfr

masks: ['**/*.hpp']

repository: https://github.com/kfrlib/kfr/blob/{TAG}/include/kfr/{FILE}#L{LINE}

groups:
filter: "Filter API"
cpuid: "Runtime CPU detection"
cometa: "CoMeta - metaprogramming"
testo: "Testo - unit test"
dft: "DFT"
binary_io: "Generic IO"
audio_io: "Audio IO"
plotting: "Plotting (uses matplotlib)"
string_io: "String conversion/printing values"
biquad: "Biquad filter and design functions"
fir: "FIR filter and design functions"
window: "Window functions"
sample_rate_conversion: "Sample rate conversion"
oscillators: "Oscillator functions"
dsp_extra: "Extra DSP functions"
ebu: "EBU R128 functions"
types: "Types"
memory: "Memory allocation"
conversion: "Conversion functions"
complex: "Complex functions"
constants: "Constants"
logical: "Logical functions"
basic_math: "Basic math functions"
exponential: "Exponential/Logarithm and other functions"
round: "Rounding functions"
math: "Math functions"
read_write: "Loading/storing SIMD"
saturation: "Saturated arithmetics functions"
trigonometric: "Trigonometric functions"
hyperbolic: "Hyperbolic functions"
shuffle: "SIMD Shuffle functions"
horizontal: "SIMD shuffle Functions"
other_math: "Other math functions"
interpolation: "Interpolation functions"
expressions: "Expressions"
generators: "Generator expressions"
random: "PRNG functions and expressions"
array: "Array functions"
utility: "Utility functions"

@@ -0,0 +1,3 @@
# How to apply a Biquad filter

[See also a gallery with results of applying various Biquad filters](bq_gallery.md)
@@ -0,0 +1,123 @@
# Biquad filters code & examples

## Biquad high shelf filter (0.3, +9dB)

Code
```c++ linenums="1"
const std::string options = "phaseresp=True";
univector<fbase, 128> output;
biquad_params<fbase> bq[] = { biquad_highshelf(0.3, +9.0) };
output = biquad(bq, unitimpulse());
plot_save("biquad_highshelf", output, options + ", title='Biquad high shelf filter (0.3, +9)'");
```
Result

![biquad_highshelf](img/biquad_highshelf.svg)

## Biquad Low pass filter (0.2, 0.9)

Code
```c++ linenums="1"
const std::string options = "phaseresp=True";
univector<fbase, 128> output;
biquad_params<fbase> bq[] = { biquad_lowpass(0.2, 0.9) };
output = biquad(bq, unitimpulse());
plot_save("biquad_lowpass", output, options + ", title='Biquad Low pass filter (0.2, 0.9)'");
```
Result

![biquad_lowpass](img/biquad_lowpass.svg)


## Biquad low shelf filter (0.3, -1dB)

Code
```c++ linenums="1"
const std::string options = "phaseresp=True";
univector<fbase, 128> output;
biquad_params<fbase> bq[] = { biquad_lowshelf(0.3, -1.0) };
output = biquad(bq, unitimpulse());
plot_save("biquad_lowshelf", output, options + ", title='Biquad low shelf filter (0.3, -1)'");
```
Result

![biquad_lowshelf](img/biquad_lowshelf.svg)

## Four Biquad Notch filters

Code
```c++ linenums="1"
const std::string options = "phaseresp=True";
univector<fbase, 128> output;
biquad_params<fbase> bq[] = { biquad_notch(0.1, 0.5), biquad_notch(0.2, 0.5), biquad_notch(0.3, 0.5),
biquad_notch(0.4, 0.5) };
output = biquad(bq, unitimpulse());
plot_save("biquad_notch", output, options + ", title='Four Biquad Notch filters'");
```
Result

![biquad_notch](img/biquad_notch.svg)

## Biquad Peak filter (0.2, 0.5, +9dB)

Code
```c++ linenums="1"
const std::string options = "phaseresp=True";
univector<fbase, 128> output;
biquad_params<fbase> bq[] = { biquad_peak(0.3, 0.5, +9.0) };
output = biquad(bq, unitimpulse());
plot_save("biquad_peak", output, options + ", title='Biquad Peak filter (0.2, 0.5, +9)'");
```
Result

![biquad_peak](img/biquad_peak.svg)

## Biquad Peak filter (0.3, 3, -2dB)

Code
```c++ linenums="1"
const std::string options = "phaseresp=True";
univector<fbase, 128> output;
biquad_params<fbase> bq[] = { biquad_peak(0.3, 3.0, -2.0) };
output = biquad(bq, unitimpulse());
plot_save("biquad_peak2", output, options + ", title='Biquad Peak filter (0.3, 3, -2)'");
```
Result

![biquad_peak2](img/biquad_peak2.svg)

## Biquad Peak filter (0.3, 3, -2dB)

Code
```c++ linenums="1"
const std::string options = "phaseresp=True";
univector<fbase, 128> output;
biquad_params<fbase> bq[] = { biquad_bandpass(0.25, 0.2) };
output = biquad(bq, unitimpulse());
plot_save("biquad_bandpass", output, options + ", title='Biquad band pass (0.25, 0.2)'");
```
Result

![biquad_bandpass](img/biquad_bandpass.svg)

## Biquad High pass filter (0.3, 0.1)

Code
```c++ linenums="1"
const std::string options = "phaseresp=True";
univector<fbase, 128> output;
biquad_params<fbase> bq[] = { biquad_highpass(0.3, 0.1) };
output = biquad(bq, unitimpulse());
plot_save("biquad_highpass", output, options + ", title='Biquad High pass filter (0.3, 0.1)'");
```
Result

![biquad_highpass](img/biquad_highpass.svg)

@@ -0,0 +1,70 @@
# How to convert sample type

## Convert one channel of audio

If input and output formats are both known at compile time

```c++
const float input[7] = {0.f, 0.25f, -0.25f, 0.5f, -0.5f, 1.f, -1.f};
int16_t output[7];
convert(output, input, 7);
println(make_univector(output, 7));
```

If input format is not known at compile time

```c++
const void* input;
int16_t* output;
size_t size;
audio_sample_type in_type = audio_sample_type::i24; // known at runtime
convert(output, input, in_type, size);
```

If output format is not known at compile time

```c++
const float* input;
void* output;
size_t size;
audio_sample_type out_type = audio_sample_type::i24; // known at runtime
convert(output, out_type, input, size);
```

## Interleaving

```c++
const float* inputs[];
int16_t* output;
size_t channels;
size_t size;
interleave(output, inputs, channels, size);
```

## Deinterleaving

```c++
const float* input;
int16_t* outputs[];
size_t channels;
size_t size;
deinterleave(outputs, input, channels, size);
```

## Convert single audio sample

```c++
i24 s = convert_sample<i24, f32>(1.f);
```

## Supported formats

Constant | Type | Description | Range
-------- | ---- | ----------- | -----
audio_sample_type::i8 | i8 | 8-bit signed | -127..+127
audio_sample_type::i16 | i16 | 16-bit signed | -32767..+32767
audio_sample_type::i24 | i24 | 24-bit signed | -8388607..+8388607
audio_sample_type::i32 | i32 | 32-bit signed | -2147483647..+2147483647
audio_sample_type::i64 | i64 | 64-bit signed | -9223372036854775807..+9223372036854775807
audio_sample_type::f32 | f32 | 32-bit IEEE | -1..+1
audio_sample_type::f64 | f64 | 64-bit IEEE | -1..+1
@@ -0,0 +1,45 @@
# How to mix stereo channels

## L/R to M/S

Input/output data. [See how to pass data to KFR](types.md)
```c++
univector<float> left;
univector<float> right;
univector<float> middle;
univector<float> side;
```
Code
```c++
unpack(middle, side) = mixdown_stereo(left, right, matrix_halfsum_halfdiff());
```

1. `mixdown_stereo` function takes arrays representing L and R channels and returns values multiplied by the given matrix.
1. `matrix_halfsum_halfdiff` specifies that $(L+R)/2$ and $(L-R)/2$ must be returned
1. `unpack` writes M+S values to the given arrays

## M/S to L/R

Code
```c++
unpack(left, right) = mixdown_stereo(middle, side, matrix_sum_diff());
```
1. `matrix_sum_diff` specifies that $M+S$ and $M-S$ must be returned, effectively reverting back L and R channels


## Downmix to mono

Input/output data.
```c++
univector<float> left;
univector<float> right;
univector<float> mono;
```
Code
```c++
mono = (left + right) * 0.5f;
```
or, depending on what results you want to get
```c++
mono = left + right;
```
@@ -0,0 +1,70 @@
# How to apply Convolution Reverb

## Mono version

Input/Output data: [See how to pass data to KFR](types.md)
```c++
univector<float> audio;
univector<float> impulse_response;
```
Code
```c++
convolve_filter<float> reverb(impulse_response);
reverb.apply(audio);
```

!!! note
`convolve_filter` uses [Filter API](filters.md) and preserves its internal state between calls to `apply`.
Audio can be processed in chunks.
Use `reset` function to reset its internal state.

`convolve_filter` has zero latency.

Internally, [FFT](dft.md) is used for performing convolution

## True stereo version

Formula

$$
\begin{aligned}
out_{L} &= in_{L} * ir_{LL} + in_{R} * ir_{RL}\\
out_{R} &= in_{L} * ir_{LR} + in_{R} * ir_{RR}
\end{aligned}
$$

where $*$ is convolution operator.
Input/Output data:
```c++
univector<float, 2> stereo_audio;
univector<float, 4> impulse_response;
// impulse_response[0] is left to left
// impulse_response[1] is right to left
// impulse_response[2] is left to right
// impulse_response[3] is right to right
```
Code
```c++
// Prepare filters
convolve_filter<float> reverb_LL(impulse_response[0]);
convolve_filter<float> reverb_LR(impulse_response[1]);
convolve_filter<float> reverb_RL(impulse_response[2]);
convolve_filter<float> reverb_RR(impulse_response[3]);
// Allocate temp data
univector<float> tmp1(stereo_audio[0].size());
univector<float> tmp2(stereo_audio[0].size());
univector<float> tmp3(stereo_audio[0].size());
univector<float> tmp4(stereo_audio[0].size());
// Apply convolution
reverb_LL.apply(tmp1, audio[0]);
reverb_RL.apply(tmp2, audio[1]);
reverb_LR.apply(tmp3, audio[0]);
reverb_RR.apply(tmp4, audio[1]);
// final downmix
audio[0] = tmp1 + tmp2;
audio[1] = tmp3 + tmp4;
```

0 comments on commit 7998955

Please sign in to comment.
You can’t perform that action at this time.