-
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathSF2Engine.mm
More file actions
165 lines (139 loc) · 5.09 KB
/
SF2Engine.mm
File metadata and controls
165 lines (139 loc) · 5.09 KB
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
161
162
163
164
165
// Copyright © 2023 Brad Howes. All rights reserved.
#include <iostream>
#include "SF2Engine.hpp"
#include "SF2Lib/Render/Engine/Engine.hpp"
#include "SF2Lib/MIDI/MIDI.hpp"
namespace Eng = SF2::Render::Engine;
SF2Engine::SF2Engine() noexcept
: impl_{nullptr}
{
std::cout << "SF2Engine::SF2Engine" << std::endl;
}
SF2Engine::~SF2Engine() noexcept
{
auto allocated = impl_.get() != nullptr;
auto useCount = impl_.use_count();
std::cout << "SF2Engine::~SF2Engine - allocated: " << allocated << " useCount: " << useCount << std::endl;
}
void SF2Engine::create(double sampleRate, NSUInteger voiceCount)
{
std::cout << "SF2Engine::create" << std::endl;
assert(impl_.get() == nullptr);
impl_.reset(new Eng::Engine(sampleRate, voiceCount, Eng::Engine::Interpolator::cubic4thOrder, 0.85));
}
bool
SF2Engine::setRenderingFormat(NSInteger busCount, AVAudioFormat *format, AUAudioFrameCount maxFramesToRender) const noexcept
{
impl_->setRenderingFormat(busCount, format, maxFramesToRender);
return impl_->isRendering();
}
AUInternalRenderBlock
SF2Engine::getRenderBlock() const noexcept {
// Technically, this makes the class "unsafe" since it is allowing the internal engine pointer to escape its wrapper.
// We do this under the assumption that Apple won't hold onto this block after rendering has stopped.
NSInteger bus = 0;
auto engine = impl_.get();
assert(engine != nullptr);
return ^AUAudioUnitStatus(AudioUnitRenderActionFlags* _Nonnull actionFlags, const AudioTimeStamp* _Nonnull timestamp,
AUAudioFrameCount frameCount, NSInteger outputBusNumber, AudioBufferList* _Nonnull output,
const AURenderEvent* __nullable realtimeEventListHead,
AURenderPullInputBlock __nullable __unsafe_unretained) {
// NOTE: do not pass on the AURenderPullInputBlock since we are the source of all audio. Doing so will result in an AU error
// from the render routine resulting in no audio output.
return engine->processAndRender(timestamp, frameCount, outputBusNumber, output, realtimeEventListHead, nullptr);
};
}
AUAudioUnitStatus
SF2Engine::processAndRender(const AudioTimeStamp* timestamp, UInt32 frameCount, NSInteger outputBusNumber,
AudioBufferList* output, const AURenderEvent* realtimeEventListHead,
AURenderPullInputBlock) const noexcept
{
return impl_->processAndRender(timestamp, frameCount, outputBusNumber, output, realtimeEventListHead, nullptr);
}
AUParameterTree*
SF2Engine::getParameterTree() const noexcept
{
return impl_->parameterTree();
}
std::string
SF2Engine::activePresetName() const noexcept
{
return impl_->activePresetName();
}
std::vector<uint8_t>
SF2Engine::createLoadFileUsePresetPayload(std::string filePath, size_t presetIndex) noexcept
// SF2::MIDI::GeneratorOverrideVector overrides) noexcept
{
SF2::MIDI::GeneratorOverrideVector overrides;
return SF2::Render::Engine::Engine::createLoadFileUsePresetPayload(filePath, presetIndex, overrides);
}
void
SF2Engine::loadFileAndPreset(std::string path, size_t presetIndex) noexcept {
impl_->loadFileAndPreset(path, presetIndex);
}
std::vector<uint8_t>
SF2Engine::createLoadBookmarkUsePresetPayload(NSData* bookmark, size_t presetIndex) noexcept
// SF2::MIDI::GeneratorOverrideVector overrides) noexcept
{
SF2::MIDI::GeneratorOverrideVector overrides;
return SF2::Render::Engine::Engine::createLoadBookmarkUsePresetPayload(bookmark, presetIndex, overrides);
}
void
SF2Engine::loadBookmarkAndPreset(NSData* bookmark, size_t presetIndex) noexcept {
impl_->loadBookmarkAndPreset(bookmark, presetIndex);
}
std::array<uint8_t, 1>
SF2Engine::createResetCommandPayload() noexcept
{
return SF2::Render::Engine::Engine::createResetCommandPayload();
}
std::array<uint8_t, 9>
SF2Engine::createUseBankProgramPayload(uint16_t bank, uint8_t program) noexcept
{
return SF2::Render::Engine::Engine::createUseBankProgramPayload(bank, program);
}
std::array<uint8_t, 3>
SF2Engine::createChannelMessagePayload(uint8_t channelMessage, uint8_t content) noexcept
{
return SF2::Render::Engine::Engine::createChannelMessagePayload(SF2::MIDI::ControlChange(channelMessage), content );
}
std::array<uint8_t, 3>
SF2Engine::createAllNotesOffPayload() noexcept
{
return SF2::Render::Engine::Engine::createAllNotesOffPayload();
}
std::array<uint8_t, 3>
SF2Engine::createAllSoundOffPayload() noexcept
{
return SF2::Render::Engine::Engine::createAllSoundOffPayload();
}
size_t
SF2Engine::activeVoiceCount() const noexcept
{
return impl_->activeVoiceCount();
}
bool
SF2Engine::monophonicModeEnabled() const noexcept
{
return impl_->monophonicModeEnabled();
}
bool
SF2Engine::polyphonicModeEnabled() const noexcept
{
return impl_->polyphonicModeEnabled();
}
bool
SF2Engine::portamentoModeEnabled() const noexcept
{
return impl_->portamentoModeEnabled();
}
bool
SF2Engine::oneVoicePerKeyModeEnabled() const noexcept
{
return impl_->oneVoicePerKeyModeEnabled();
}
bool
SF2Engine::retriggerModeEnabled() const noexcept
{
return impl_->retriggerModeEnabled();
}