File size: 3,228 Bytes
8c39918
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include "AudioEngine.h"
#include "SamplerVoice.h"

AudioEngine::AudioEngine()
{
    // Initialize 8 sampler voices for 8 pads
    for (int i = 0; i < 8; ++i)
    {
        voices.push_back(std::make_unique<SamplerVoice>());
    }
}

AudioEngine::~AudioEngine() = default;

void AudioEngine::prepareToPlay(double sampleRate, int samplesPerBlock)
{
    currentSampleRate = sampleRate;
    sampleBuffer.setSize(2, samplesPerBlock);
    
    for (auto& voice : voices)
    {
        voice->prepareToPlay(sampleRate, samplesPerBlock);
    }
}

void AudioEngine::releaseResources()
{
    for (auto& voice : voices)
    {
        voice->releaseResources();
    }
}

void AudioEngine::processBlock(juce::AudioBuffer<float>& buffer, juce::MidiBuffer& midiMessages)
{
    const juce::ScopedLock sl(lock);
    
    buffer.clear();
    
    // Process MIDI messages
    for (const auto metadata : midiMessages)
    {
        const auto msg = metadata.getMessage();
        
        if (msg.isNoteOn())
        {
            const int note = msg.getNoteNumber();
            if (note >= 0 && note < 8)
            {
                voices[note]->noteOn(msg.getNoteNumber(), msg.getVelocity());
            }
        }
        else if (msg.isNoteOff())
        {
            const int note = msg.getNoteNumber();
            if (note >= 0 && note < 8)
            {
                voices[note]->noteOff();
            }
        }
    }
    
    // Render all voices
    for (auto& voice : voices)
    {
        voice->renderNextBlock(buffer, 0, buffer.getNumSamples());
    }
}

void AudioEngine::loadSample(int padIndex, const juce::String& filePath)
{
    const juce::ScopedLock sl(lock);
    
    if (padIndex >= 0 && padIndex < 8)
    {
        voices[padIndex]->loadSample(filePath);
    }
}

void AudioEngine::playPad(int padIndex)
{
    const juce::ScopedLock sl(lock);
    
    if (padIndex >= 0 && padIndex < 8)
    {
        voices[padIndex]->noteOn(60, 127);
    }
}

void AudioEngine::stopPad(int padIndex)
{
    const juce::ScopedLock sl(lock);
    
    if (padIndex >= 0 && padIndex < 8)
    {
        voices[padIndex]->noteOff();
    }
}

void AudioEngine::stopAll()
{
    const juce::ScopedLock sl(lock);
    
    for (auto& voice : voices)
    {
        voice->noteOff();
    }
}

void AudioEngine::setBpm(double bpm)
{
    currentBpm = bpm;
    
    // Update tempo-dependent effects
    for (auto& voice : voices)
    {
        voice->setTempo(bpm);
    }
}

void AudioEngine::setLoopMode(int padIndex, bool shouldLoop)
{
    const juce::ScopedLock sl(lock);
    
    if (padIndex >= 0 && padIndex < 8)
    {
        voices[padIndex]->setLoopMode(shouldLoop);
    }
}

void AudioEngine::setVolume(int padIndex, float volume)
{
    const juce::ScopedLock sl(lock);
    
    if (padIndex >= 0 && padIndex < 8)
    {
        voices[padIndex]->setVolume(volume);
    }
}

void AudioEngine::clearPad(int padIndex)
{
    const juce::ScopedLock sl(lock);
    
    if (padIndex >= 0 && padIndex < 8)
    {
        voices[padIndex]->clear();
    }
}

void AudioEngine::setReverb(float amount)
{
    // TODO: Implement reverb effect
}

void AudioEngine::setDelay(float time, float feedback)
{
    // TODO: Implement delay effect
}