summaryrefslogtreecommitdiffstats
path: root/src/audio_core/hle/filter.h
blob: 5350e2857d1c08f0114321e47e246eba950188a5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
// Copyright 2016 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.

#pragma once

#include <array>
#include "audio_core/hle/common.h"
#include "audio_core/hle/dsp.h"
#include "common/common_types.h"

namespace DSP {
namespace HLE {

/// Preprocessing filters. There is an independent set of filters for each Source.
class SourceFilters final {
public:
    SourceFilters() {
        Reset();
    }

    /// Reset internal state.
    void Reset();

    /**
     * Enable/Disable filters
     * See also: SourceConfiguration::Configuration::simple_filter_enabled,
     *           SourceConfiguration::Configuration::biquad_filter_enabled.
     * @param simple If true, enables the simple filter. If false, disables it.
     * @param biquad If true, enables the biquad filter. If false, disables it.
     */
    void Enable(bool simple, bool biquad);

    /**
     * Configure simple filter.
     * @param config Configuration from DSP shared memory.
     */
    void Configure(SourceConfiguration::Configuration::SimpleFilter config);

    /**
     * Configure biquad filter.
     * @param config Configuration from DSP shared memory.
     */
    void Configure(SourceConfiguration::Configuration::BiquadFilter config);

    /**
     * Processes a frame in-place.
     * @param frame Audio samples to process. Modified in-place.
     */
    void ProcessFrame(StereoFrame16& frame);

private:
    bool simple_filter_enabled;
    bool biquad_filter_enabled;

    struct SimpleFilter {
        SimpleFilter() {
            Reset();
        }

        /// Resets internal state.
        void Reset();

        /**
         * Configures this filter with application settings.
         * @param config Configuration from DSP shared memory.
         */
        void Configure(SourceConfiguration::Configuration::SimpleFilter config);

        /**
         * Processes a single stereo PCM16 sample.
         * @param x0 Input sample
         * @return Output sample
         */
        std::array<s16, 2> ProcessSample(const std::array<s16, 2>& x0);

    private:
        // Configuration
        s32 a1, b0;
        // Internal state
        std::array<s16, 2> y1;
    } simple_filter;

    struct BiquadFilter {
        BiquadFilter() {
            Reset();
        }

        /// Resets internal state.
        void Reset();

        /**
         * Configures this filter with application settings.
         * @param config Configuration from DSP shared memory.
         */
        void Configure(SourceConfiguration::Configuration::BiquadFilter config);

        /**
         * Processes a single stereo PCM16 sample.
         * @param x0 Input sample
         * @return Output sample
         */
        std::array<s16, 2> ProcessSample(const std::array<s16, 2>& x0);

    private:
        // Configuration
        s32 a1, a2, b0, b1, b2;
        // Internal state
        std::array<s16, 2> x1;
        std::array<s16, 2> x2;
        std::array<s16, 2> y1;
        std::array<s16, 2> y2;
    } biquad_filter;
};

} // namespace HLE
} // namespace DSP