chenlh
2026-03-26 36e42207da4c088b5bfd96f2cfc8944f890440d7
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
 
#pragma once
 
#include <stdio.h>
#include <vector>
#include "Parameters.h"
#include "ReverbChannel.h"
#include "AllpassDiffuser.h"
#include "MultitapDelay.h"
#include "Utils.h"
 
namespace ReverbHallRoom
{
    class ReverbController
    {
    private:
        int samplerate;
 
        ReverbChannel channelL;
        ReverbChannel channelR;
        double parameters[(int)Parameter::COUNT] = {0};
 
    public:
        ReverbController(int samplerate = 48000) :
            channelL(samplerate, ChannelLR::Left),
            channelR(samplerate, ChannelLR::Right)
        {
            this->samplerate = samplerate;
        }
 
        int GetSamplerate()
        {
            return samplerate;
        }
 
        void SetSamplerate(int samplerate)
        {
            this->samplerate = samplerate;
            channelL.SetSamplerate(samplerate);
            channelR.SetSamplerate(samplerate);
        }
 
        int GetParameterCount()
        {
            return Parameter::COUNT;
        }
 
        double* GetAllParameters()
        {
            return parameters;
        }
 
        void SetParameter(int paramId, double value)
        {
            parameters[paramId] = value;
            auto scaled = ScaleParam(value, paramId);
            channelL.SetParameter(paramId, scaled);
            channelR.SetParameter(paramId, scaled);
        }
 
        void ClearBuffers()
        {
            channelL.ClearBuffers();
            channelR.ClearBuffers();
        }
 
        void Process(float* inL, float* inR, float* outL, float* outR, int bufSize)
        {
            float outLTemp[BUFFER_SIZE];
            float outRTemp[BUFFER_SIZE];
 
            while (bufSize > 0)
            {
                int subBufSize = bufSize > BUFFER_SIZE ? BUFFER_SIZE : bufSize;
                ProcessChunk(inL, inR, outLTemp, outRTemp, subBufSize);
                Utils::Copy(outL, outLTemp, subBufSize);
                Utils::Copy(outR, outRTemp, subBufSize);
                inL = &inL[subBufSize];
                inR = &inR[subBufSize];
                outL = &outL[subBufSize];
                outR = &outR[subBufSize];
                bufSize -= subBufSize;
            }
        }
 
    private:
        void ProcessChunk(float* inL, float* inR, float* outL, float* outR, int bufSize)
        {
            float leftChannelIn[BUFFER_SIZE];
            float rightChannelIn[BUFFER_SIZE];
 
            float inputMix = ScaleParam(parameters[Parameter::InputMix], Parameter::InputMix);
            float cm = inputMix * 0.5;
            float cmi = (1 - cm);
 
            for (int i = 0; i < bufSize; i++)
            {
                leftChannelIn[i] = inL[i] * cmi + inR[i] * cm;
                rightChannelIn[i] = inR[i] * cmi + inL[i] * cm;
            }
 
            channelL.Process(leftChannelIn, outL, bufSize);
            channelR.Process(rightChannelIn, outR, bufSize);
        }
    };
}