├── .github
├── FUNDING.yml
└── workflows
│ └── ci.yml
├── .gitignore
├── Directory.Build.props
├── Directory.Build.targets
├── NPlug.Samples.sln
├── NPlug.SimpleDelay
├── NPlug.SimpleDelay.csproj
├── SimpleDelayController.cs
├── SimpleDelayModel.cs
├── SimpleDelayPlugin.cs
└── SimpleDelayProcessor.cs
├── NPlug.SimpleProgramChange
├── NPlug.SimpleProgramChange.csproj
├── SimpleProgramChangeController.cs
├── SimpleProgramChangeModel.cs
├── SimpleProgramChangePlugin.cs
└── SimpleProgramChangeProcessor.cs
├── global.json
├── license.txt
└── readme.md
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [xoofx]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: ci
2 |
3 | on:
4 | push:
5 | paths-ignore:
6 | - 'readme.md'
7 | pull_request:
8 |
9 | jobs:
10 | build:
11 | runs-on: windows-latest
12 |
13 | steps:
14 | - name: Checkout
15 | uses: actions/checkout@v3
16 | with:
17 | submodules: true
18 | fetch-depth: 0
19 |
20 | - name: Install .NET 7.0
21 | uses: actions/setup-dotnet@v3
22 | with:
23 | dotnet-version: '7.0.x'
24 |
25 | - name: Build
26 | shell: bash
27 | run: |
28 | dotnet build -c Release
29 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.rsuser
8 | *.suo
9 | *.user
10 | *.userosscache
11 | *.sln.docstates
12 |
13 | # Rider
14 | .idea/
15 |
16 | # User-specific files (MonoDevelop/Xamarin Studio)
17 | *.userprefs
18 |
19 | # Mono auto generated files
20 | mono_crash.*
21 |
22 | # Build results
23 | [Dd]ebug/
24 | [Dd]ebugPublic/
25 | [Rr]elease/
26 | [Rr]eleases/
27 | x64/
28 | x86/
29 | [Ww][Ii][Nn]32/
30 | [Aa][Rr][Mm]/
31 | [Aa][Rr][Mm]64/
32 | ext/**/build/
33 | bld/
34 | [Bb]in/
35 | [Oo]bj/
36 | [Ll]og/
37 | [Ll]ogs/
38 |
39 | # Visual Studio 2015/2017 cache/options directory
40 | .vs/
41 | # Uncomment if you have tasks that create the project's static files in wwwroot
42 | #wwwroot/
43 |
44 | # Visual Studio 2017 auto generated files
45 | Generated\ Files/
46 |
47 | # MSTest test Results
48 | [Tt]est[Rr]esult*/
49 | [Bb]uild[Ll]og.*
50 |
51 | # NUnit
52 | *.VisualState.xml
53 | TestResult.xml
54 | nunit-*.xml
55 |
56 | # Build Results of an ATL Project
57 | [Dd]ebugPS/
58 | [Rr]eleasePS/
59 | dlldata.c
60 |
61 | # Benchmark Results
62 | BenchmarkDotNet.Artifacts/
63 |
64 | # .NET Core
65 | project.lock.json
66 | project.fragment.lock.json
67 | artifacts/
68 |
69 | # ASP.NET Scaffolding
70 | ScaffoldingReadMe.txt
71 |
72 | # StyleCop
73 | StyleCopReport.xml
74 |
75 | # Files built by Visual Studio
76 | *_i.c
77 | *_p.c
78 | *_h.h
79 | *.ilk
80 | *.meta
81 | *.obj
82 | *.iobj
83 | *.pch
84 | *.pdb
85 | *.ipdb
86 | *.pgc
87 | *.pgd
88 | *.rsp
89 | *.sbr
90 | *.tlb
91 | *.tli
92 | *.tlh
93 | *.tmp
94 | *.tmp_proj
95 | *_wpftmp.csproj
96 | *.log
97 | *.vspscc
98 | *.vssscc
99 | .builds
100 | *.pidb
101 | *.svclog
102 | *.scc
103 |
104 | # Chutzpah Test files
105 | _Chutzpah*
106 |
107 | # Visual C++ cache files
108 | ipch/
109 | *.aps
110 | *.ncb
111 | *.opendb
112 | *.opensdf
113 | *.sdf
114 | *.cachefile
115 | *.VC.db
116 | *.VC.VC.opendb
117 |
118 | # Visual Studio profiler
119 | *.psess
120 | *.vsp
121 | *.vspx
122 | *.sap
123 |
124 | # Visual Studio Trace Files
125 | *.e2e
126 |
127 | # TFS 2012 Local Workspace
128 | $tf/
129 |
130 | # Guidance Automation Toolkit
131 | *.gpState
132 |
133 | # ReSharper is a .NET coding add-in
134 | _ReSharper*/
135 | *.[Rr]e[Ss]harper
136 | *.DotSettings.user
137 |
138 | # TeamCity is a build add-in
139 | _TeamCity*
140 |
141 | # DotCover is a Code Coverage Tool
142 | *.dotCover
143 |
144 | # AxoCover is a Code Coverage Tool
145 | .axoCover/*
146 | !.axoCover/settings.json
147 |
148 | # Coverlet is a free, cross platform Code Coverage Tool
149 | coverage.*[.json, .xml, .info]
150 |
151 | # Visual Studio code coverage results
152 | *.coverage
153 | *.coveragexml
154 |
155 | # NCrunch
156 | _NCrunch_*
157 | .*crunch*.local.xml
158 | nCrunchTemp_*
159 |
160 | # MightyMoose
161 | *.mm.*
162 | AutoTest.Net/
163 |
164 | # Web workbench (sass)
165 | .sass-cache/
166 |
167 | # Installshield output folder
168 | [Ee]xpress/
169 |
170 | # DocProject is a documentation generator add-in
171 | DocProject/buildhelp/
172 | DocProject/Help/*.HxT
173 | DocProject/Help/*.HxC
174 | DocProject/Help/*.hhc
175 | DocProject/Help/*.hhk
176 | DocProject/Help/*.hhp
177 | DocProject/Help/Html2
178 | DocProject/Help/html
179 |
180 | # Click-Once directory
181 | publish/
182 |
183 | # Publish Web Output
184 | *.[Pp]ublish.xml
185 | *.azurePubxml
186 | # Note: Comment the next line if you want to checkin your web deploy settings,
187 | # but database connection strings (with potential passwords) will be unencrypted
188 | *.pubxml
189 | *.publishproj
190 |
191 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
192 | # checkin your Azure Web App publish settings, but sensitive information contained
193 | # in these scripts will be unencrypted
194 | PublishScripts/
195 |
196 | # NuGet Packages
197 | *.nupkg
198 | # NuGet Symbol Packages
199 | *.snupkg
200 | # The packages folder can be ignored because of Package Restore
201 | **/[Pp]ackages/*
202 | # except build/, which is used as an MSBuild target.
203 | !**/[Pp]ackages/build/
204 | # Uncomment if necessary however generally it will be regenerated when needed
205 | #!**/[Pp]ackages/repositories.config
206 | # NuGet v3's project.json files produces more ignorable files
207 | *.nuget.props
208 | *.nuget.targets
209 |
210 | # Microsoft Azure Build Output
211 | csx/
212 | *.build.csdef
213 |
214 | # Microsoft Azure Emulator
215 | ecf/
216 | rcf/
217 |
218 | # Windows Store app package directories and files
219 | AppPackages/
220 | BundleArtifacts/
221 | Package.StoreAssociation.xml
222 | _pkginfo.txt
223 | *.appx
224 | *.appxbundle
225 | *.appxupload
226 |
227 | # Visual Studio cache files
228 | # files ending in .cache can be ignored
229 | *.[Cc]ache
230 | # but keep track of directories ending in .cache
231 | !?*.[Cc]ache/
232 |
233 | # Others
234 | ClientBin/
235 | ~$*
236 | *~
237 | *.dbmdl
238 | *.dbproj.schemaview
239 | *.jfm
240 | *.pfx
241 | *.publishsettings
242 | orleans.codegen.cs
243 |
244 | # Including strong name files can present a security risk
245 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
246 | #*.snk
247 |
248 | # Since there are multiple workflows, uncomment next line to ignore bower_components
249 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
250 | #bower_components/
251 |
252 | # RIA/Silverlight projects
253 | Generated_Code/
254 |
255 | # Backup & report files from converting an old project file
256 | # to a newer Visual Studio version. Backup files are not needed,
257 | # because we have git ;-)
258 | _UpgradeReport_Files/
259 | Backup*/
260 | UpgradeLog*.XML
261 | UpgradeLog*.htm
262 | ServiceFabricBackup/
263 | *.rptproj.bak
264 |
265 | # SQL Server files
266 | *.mdf
267 | *.ldf
268 | *.ndf
269 |
270 | # Business Intelligence projects
271 | *.rdl.data
272 | *.bim.layout
273 | *.bim_*.settings
274 | *.rptproj.rsuser
275 | *- [Bb]ackup.rdl
276 | *- [Bb]ackup ([0-9]).rdl
277 | *- [Bb]ackup ([0-9][0-9]).rdl
278 |
279 | # Microsoft Fakes
280 | FakesAssemblies/
281 |
282 | # GhostDoc plugin setting file
283 | *.GhostDoc.xml
284 |
285 | # Node.js Tools for Visual Studio
286 | .ntvs_analysis.dat
287 | node_modules/
288 |
289 | # Visual Studio 6 build log
290 | *.plg
291 |
292 | # Visual Studio 6 workspace options file
293 | *.opt
294 |
295 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
296 | *.vbw
297 |
298 | # Visual Studio LightSwitch build output
299 | **/*.HTMLClient/GeneratedArtifacts
300 | **/*.DesktopClient/GeneratedArtifacts
301 | **/*.DesktopClient/ModelManifest.xml
302 | **/*.Server/GeneratedArtifacts
303 | **/*.Server/ModelManifest.xml
304 | _Pvt_Extensions
305 |
306 | # Paket dependency manager
307 | .paket/paket.exe
308 | paket-files/
309 |
310 | # FAKE - F# Make
311 | .fake/
312 |
313 | # CodeRush personal settings
314 | .cr/personal
315 |
316 | # Python Tools for Visual Studio (PTVS)
317 | __pycache__/
318 | *.pyc
319 |
320 | # Cake - Uncomment if you are using it
321 | # tools/**
322 | # !tools/packages.config
323 |
324 | # Tabs Studio
325 | *.tss
326 |
327 | # Telerik's JustMock configuration file
328 | *.jmconfig
329 |
330 | # BizTalk build output
331 | *.btp.cs
332 | *.btm.cs
333 | *.odx.cs
334 | *.xsd.cs
335 |
336 | # OpenCover UI analysis results
337 | OpenCover/
338 |
339 | # Azure Stream Analytics local run output
340 | ASALocalRun/
341 |
342 | # MSBuild Binary and Structured Log
343 | *.binlog
344 |
345 | # NVidia Nsight GPU debugger configuration file
346 | *.nvuser
347 |
348 | # MFractors (Xamarin productivity tool) working folder
349 | .mfractor/
350 |
351 | # Local History for Visual Studio
352 | .localhistory/
353 |
354 | # BeatPulse healthcheck temp database
355 | healthchecksdb
356 |
357 | # Backup folder for Package Reference Convert tool in Visual Studio 2017
358 | MigrationBackup/
359 |
360 | # Ionide (cross platform F# VS Code tools) working folder
361 | .ionide/
362 |
363 | # Rust
364 | /lib/blake3_dotnet/target
365 | Cargo.lock
366 |
367 | # Tmp folders
368 | tmp/
369 | [Tt]emp/
370 |
371 | # Remove artifacts produced by dotnet-releaser
372 | artifacts-dotnet-releaser/
373 |
--------------------------------------------------------------------------------
/Directory.Build.props:
--------------------------------------------------------------------------------
1 |
2 |
3 | $(MSBuildThisFileDirectory)../src/NPlug.samples.targets
4 |
5 |
--------------------------------------------------------------------------------
/Directory.Build.targets:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/NPlug.Samples.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 17
4 | VisualStudioVersion = 17.5.33424.131
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NPlug.SimpleDelay", "NPlug.SimpleDelay\NPlug.SimpleDelay.csproj", "{9CF85E5B-7A33-496F-B435-806827B6EAC6}"
7 | EndProject
8 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NPlug.SimpleProgramChange", "NPlug.SimpleProgramChange\NPlug.SimpleProgramChange.csproj", "{250F9E9C-EA18-420D-A8E3-EE5CFD8F5766}"
9 | EndProject
10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{7522EEDD-0B8D-4A54-A12F-B61DEC679C44}"
11 | ProjectSection(SolutionItems) = preProject
12 | .gitignore = .gitignore
13 | Directory.Build.props = Directory.Build.props
14 | Directory.Build.targets = Directory.Build.targets
15 | global.json = global.json
16 | license.txt = license.txt
17 | readme.md = readme.md
18 | EndProjectSection
19 | EndProject
20 | Global
21 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
22 | Debug|Any CPU = Debug|Any CPU
23 | Release|Any CPU = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
26 | {9CF85E5B-7A33-496F-B435-806827B6EAC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 | {9CF85E5B-7A33-496F-B435-806827B6EAC6}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 | {9CF85E5B-7A33-496F-B435-806827B6EAC6}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 | {9CF85E5B-7A33-496F-B435-806827B6EAC6}.Release|Any CPU.Build.0 = Release|Any CPU
30 | {250F9E9C-EA18-420D-A8E3-EE5CFD8F5766}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
31 | {250F9E9C-EA18-420D-A8E3-EE5CFD8F5766}.Debug|Any CPU.Build.0 = Debug|Any CPU
32 | {250F9E9C-EA18-420D-A8E3-EE5CFD8F5766}.Release|Any CPU.ActiveCfg = Release|Any CPU
33 | {250F9E9C-EA18-420D-A8E3-EE5CFD8F5766}.Release|Any CPU.Build.0 = Release|Any CPU
34 | EndGlobalSection
35 | GlobalSection(SolutionProperties) = preSolution
36 | HideSolutionNode = FALSE
37 | EndGlobalSection
38 | GlobalSection(ExtensibilityGlobals) = postSolution
39 | SolutionGuid = {2BF6B2DE-B7A8-4AF0-B320-91B13F94892B}
40 | EndGlobalSection
41 | EndGlobal
42 |
--------------------------------------------------------------------------------
/NPlug.SimpleDelay/NPlug.SimpleDelay.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | enable
6 | enable
7 | false
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/NPlug.SimpleDelay/SimpleDelayController.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // Licensed under the BSD-Clause 2 license.
3 | // See license.txt file in the project root for full license information.
4 |
5 | namespace NPlug.SimpleDelay;
6 |
7 | public class SimpleDelayController : AudioController
8 | {
9 | public static readonly Guid ClassId = new("484e783b-5f47-42f4-a19f-96c1fd42fb45");
10 | }
11 |
--------------------------------------------------------------------------------
/NPlug.SimpleDelay/SimpleDelayModel.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // Licensed under the BSD-Clause 2 license.
3 | // See license.txt file in the project root for full license information.
4 |
5 | namespace NPlug.SimpleDelay;
6 |
7 | public class SimpleDelayModel : AudioProcessorModel
8 | {
9 | public SimpleDelayModel() : base("NPlug.SimpleDelay")
10 | {
11 | AddByPassParameter();
12 | Delay = AddParameter(new AudioParameter("Delay", units: "sec", defaultNormalizedValue: 1.0));
13 | }
14 |
15 | public AudioParameter Delay { get; }
16 | }
17 |
--------------------------------------------------------------------------------
/NPlug.SimpleDelay/SimpleDelayPlugin.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // Licensed under the BSD-Clause 2 license.
3 | // See license.txt file in the project root for full license information.
4 |
5 | using System.Runtime.CompilerServices;
6 |
7 | namespace NPlug.SimpleDelay;
8 |
9 | public static class SimpleDelayPlugin
10 | {
11 | public static AudioPluginFactory GetFactory()
12 | {
13 | var factory = new AudioPluginFactory(new("NPlug", "https://github.com/xoofx/NPlug", "no_reply@nplug.org"));
14 | factory.RegisterPlugin(new(SimpleDelayProcessor.ClassId, "SimpleDelay", AudioProcessorCategory.Effect));
15 | factory.RegisterPlugin(new(SimpleDelayController.ClassId, "SimpleDelay Controller"));
16 | return factory;
17 | }
18 |
19 | [ModuleInitializer]
20 | internal static void ExportThisPlugin()
21 | {
22 | AudioPluginFactoryExporter.Instance = GetFactory();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/NPlug.SimpleDelay/SimpleDelayProcessor.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // Licensed under the BSD-Clause 2 license.
3 | // See license.txt file in the project root for full license information.
4 |
5 | namespace NPlug.SimpleDelay;
6 |
7 | ///
8 | /// Port of C/C++ adelay sample from https://github.com/steinbergmedia/vst3_public_sdk/tree/master/samples/vst/adelay/source
9 | ///
10 | public class SimpleDelayProcessor : AudioProcessor
11 | {
12 | private float[] _bufferLeft;
13 | private float[] _bufferRight;
14 | private int _bufferPosition;
15 |
16 | public static readonly Guid ClassId = new("7a130e07-004a-408d-a1d8-97b671f36ca1");
17 |
18 | public SimpleDelayProcessor() : base(AudioSampleSizeSupport.Float32)
19 | {
20 | _bufferLeft = Array.Empty();
21 | _bufferRight = Array.Empty();
22 | }
23 |
24 | public override Guid ControllerClassId => SimpleDelayController.ClassId;
25 |
26 |
27 | protected override bool Initialize(AudioHostApplication host)
28 | {
29 | AddAudioInput("AudioInput", SpeakerArrangement.SpeakerStereo);
30 | AddAudioOutput("AudioOutput", SpeakerArrangement.SpeakerStereo);
31 | return true;
32 | }
33 |
34 | protected override void OnActivate(bool isActive)
35 | {
36 | if (isActive)
37 | {
38 | var delayInSamples = (int)(ProcessSetupData.SampleRate * sizeof(float) + 0.5);
39 | _bufferLeft = GC.AllocateArray(delayInSamples, true);
40 | _bufferRight = GC.AllocateArray(delayInSamples, true);
41 | _bufferPosition = 0;
42 | }
43 | else
44 | {
45 | _bufferLeft = Array.Empty();
46 | _bufferRight = Array.Empty();
47 | _bufferPosition = 0;
48 | }
49 | }
50 |
51 | protected override void ProcessMain(in AudioProcessData data)
52 | {
53 | var delayInSamples = Math.Max(1, (int)(ProcessSetupData.SampleRate * Model.Delay.NormalizedValue));
54 | for (int channel = 0; channel < 2; channel++)
55 | {
56 | var inputChannel = data.Input[0].GetChannelSpanAsFloat32(ProcessSetupData, data, channel);
57 | var outputChannel = data.Output[0].GetChannelSpanAsFloat32(ProcessSetupData, data, channel);
58 |
59 | var sampleCount = data.SampleCount;
60 | var buffer = channel == 0 ? _bufferLeft : _bufferRight;
61 | var tempBufferPos = _bufferPosition;
62 | for (int sample = 0; sample < sampleCount; sample++)
63 | {
64 | var tempSample = inputChannel[sample];
65 | outputChannel[sample] = buffer[tempBufferPos];
66 | buffer[tempBufferPos] = tempSample;
67 | tempBufferPos++;
68 | if (tempBufferPos >= delayInSamples)
69 | {
70 | tempBufferPos = 0;
71 | }
72 | }
73 | }
74 |
75 | _bufferPosition += data.SampleCount;
76 | while (_bufferPosition >= delayInSamples)
77 | {
78 | _bufferPosition -= delayInSamples;
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/NPlug.SimpleProgramChange/NPlug.SimpleProgramChange.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | net8.0
5 | enable
6 | enable
7 | false
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/NPlug.SimpleProgramChange/SimpleProgramChangeController.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // Licensed under the BSD-Clause 2 license.
3 | // See license.txt file in the project root for full license information.
4 |
5 | namespace NPlug.SimpleProgramChange;
6 |
7 | public class SimpleProgramChangeController : AudioController
8 | {
9 | public static readonly Guid ClassId = new("59c17896-478b-4af1-86d8-3ba0817149d5");
10 |
11 | protected override bool Initialize(AudioHostApplication host)
12 | {
13 | SetMappingBusToUnit(BusMediaType.Event, BusDirection.Input, 0, 0, Model);
14 | return true;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/NPlug.SimpleProgramChange/SimpleProgramChangeModel.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // Licensed under the BSD-Clause 2 license.
3 | // See license.txt file in the project root for full license information.
4 |
5 | namespace NPlug.SimpleProgramChange;
6 |
7 | public class SimpleProgramChangeModel : AudioProcessorModel
8 | {
9 | public SimpleProgramChangeModel() : base("Root", DefaultProgramListBuilder)
10 | {
11 | AddByPassParameter();
12 | Gain = AddParameter(new AudioParameter("Gain", defaultNormalizedValue: 1.0));
13 | }
14 |
15 | public AudioParameter Gain { get; }
16 |
17 | private static readonly AudioProgramListBuilder DefaultProgramListBuilder = GenerateProgramListBuilder();
18 |
19 | ///
20 | /// Creates a program list that will change the gain depending on the program index
21 | ///
22 | private static AudioProgramListBuilder GenerateProgramListBuilder()
23 | {
24 | var builder = new AudioProgramListBuilder("Bank");
25 | const int programCount = 10; // Display only 10 programs
26 | for (int i = 0; i < programCount; i++)
27 | {
28 | int programIndex = i;
29 | builder.Add(model =>
30 | {
31 | // We map the gain to the program index (from 0.0 to 1.0 when changing the program)
32 | model.Gain.NormalizedValue = ((double)programIndex) / (programCount - 1);
33 | return new AudioProgram($"Prog {programIndex}");
34 | });
35 | }
36 |
37 | return builder;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/NPlug.SimpleProgramChange/SimpleProgramChangePlugin.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // Licensed under the BSD-Clause 2 license.
3 | // See license.txt file in the project root for full license information.
4 |
5 | using System.Runtime.CompilerServices;
6 |
7 | namespace NPlug.SimpleProgramChange;
8 |
9 | public static class SimpleProgramChangePlugin
10 | {
11 | public static AudioPluginFactory GetFactory()
12 | {
13 | var factory = new AudioPluginFactory(new("NPlug", "https://github.com/xoofx/NPlug", "no_reply@nplug.org"));
14 | factory.RegisterPlugin(new(SimpleProgramChangeProcessor.ClassId, "SimpleProgramChange", AudioProcessorCategory.Effect));
15 | factory.RegisterPlugin(new(SimpleProgramChangeController.ClassId, "SimpleProgramChange Controller"));
16 | return factory;
17 | }
18 |
19 | [ModuleInitializer]
20 | internal static void ExportThisPlugin()
21 | {
22 | AudioPluginFactoryExporter.Instance = GetFactory();
23 | }
24 | }
--------------------------------------------------------------------------------
/NPlug.SimpleProgramChange/SimpleProgramChangeProcessor.cs:
--------------------------------------------------------------------------------
1 | // Copyright (c) Alexandre Mutel. All rights reserved.
2 | // Licensed under the BSD-Clause 2 license.
3 | // See license.txt file in the project root for full license information.
4 |
5 | using System;
6 |
7 | namespace NPlug.SimpleProgramChange;
8 |
9 | ///
10 | /// Port of C/C++ program change sample from https://github.com/steinbergmedia/vst3_public_sdk/tree/master/samples/vst/programchange/source
11 | ///
12 | public class SimpleProgramChangeProcessor : AudioProcessor
13 | {
14 | public static readonly Guid ClassId = new("d2d46df8-3397-4acf-9008-df3396b890f2");
15 |
16 | public SimpleProgramChangeProcessor() : base(AudioSampleSizeSupport.Float32)
17 | {
18 | }
19 |
20 | public override Guid ControllerClassId => SimpleProgramChangeController.ClassId;
21 |
22 |
23 | protected override bool Initialize(AudioHostApplication host)
24 | {
25 | AddDefaultStereoAudioInput();
26 | AddDefaultStereoAudioOutput();
27 | AddDefaultEventInput();
28 | return true;
29 | }
30 |
31 | protected override void ProcessMain(in AudioProcessData data)
32 | {
33 | // Parameter changes and ByPass are handled automatically by AudioProcessor
34 |
35 | // Changing the program will make the gain ranging from 0 to 1
36 | // See SimpleProgramChangeModel
37 | var gain = (float)Model.Gain.NormalizedValue;
38 |
39 | var inputBus = data.Input[0];
40 | var outputBus = data.Output[0];
41 |
42 | for (int channel = 0; channel < inputBus.ChannelCount; channel++)
43 | {
44 | var sampleFrames = data.SampleCount;
45 | var input = inputBus.GetChannelSpanAsFloat32(ProcessSetupData, data, channel);
46 | var output = outputBus.GetChannelSpanAsFloat32(ProcessSetupData, data, channel);
47 | for(int sample = 0; sample < sampleFrames; sample++)
48 | {
49 | // apply gain
50 | output[sample] = input[sample] * gain;
51 | }
52 | }
53 | }
54 | }
--------------------------------------------------------------------------------
/global.json:
--------------------------------------------------------------------------------
1 | {
2 | "sdk": {
3 | "version": "8.0.100",
4 | "rollForward": "latestMinor",
5 | "allowPrerelease": false
6 | }
7 | }
--------------------------------------------------------------------------------
/license.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2023, Alexandre Mutel
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification
5 | , are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 |
25 | This software is also published with the following license:
26 |
27 | //----------------------------------------------------------------------------
28 | // LICENSE
29 | // (c) 2022, Steinberg Media Technologies GmbH, All Rights Reserved
30 | //----------------------------------------------------------------------------
31 | This license applies only to files referencing this license,
32 | for other files of the Software Development Kit therespective embedded license text
33 | is applicable. The license can be found at:
34 |
35 | This Software Development Kit is licensed under the terms ofthe Steinberg VST 3 License,
36 | or alternatively under the terms of the General PublicLicense (GPL) Version 3.
37 | You may use the Software Development Kit according to eitherof these licenses as it is
38 | most appropriate for your project on a case-by-case basis(commercial or not).
39 |
40 | a) Proprietary Steinberg VST 3 License
41 | The Software Development Kit may not be distributed in partsor its entirety
42 | without prior written agreement by Steinberg MediaTechnologies GmbH.
43 | The SDK must not be used to re-engineer or manipulate anytechnology used
44 | in any Steinberg or Third-party application or softwaremodule,
45 | unless permitted by law.
46 | Neither the name of the Steinberg Media Technologies GmbH northe names of its
47 | contributors may be used to endorse or promote productsderived from this
48 | software without specific prior written permission.
49 | Before publishing a software under the proprietary license, you need to obtain a copy
50 | of the License Agreement signed by Steinberg MediaTechnologies GmbH.
51 | The Steinberg VST SDK License Agreement can be found at:
52 |
53 |
54 | THE SDK IS PROVIDED BY STEINBERG MEDIA TECHNOLOGIES GMBH "ASIS" AND
55 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITEDTO, THE IMPLIED
56 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULARPURPOSE ARE DISCLAIMED.
57 | IN NO EVENT SHALL STEINBERG MEDIA TECHNOLOGIES GMBH BE LIABLEFOR ANY DIRECT,
58 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIALDAMAGES (INCLUDING,
59 | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ORSERVICES; LOSS OF USE,
60 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSEDAND ON ANY THEORY OF
61 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING NEGLIGENCE
62 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THISSOFTWARE, EVEN IF ADVISED
63 | OF THE POSSIBILITY OF SUCH DAMAGE.
64 |
65 | b) General Public License (GPL) Version 3
66 | Details of these licenses can be found at:
67 | //---------------------------------------------------------------------------------
68 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | # NPlug.Samples [](https://github.com/xoofx/NPlug.Samples/actions)
2 |
3 |
4 |
5 | This repository provides samples for creating VST3 audio native plugins with [NPlug](https://github.com/xoofx/NPlug/) and .NET7+/NativeAOT.
6 |
7 | ## Samples
8 |
9 | You need to have installed [.NET 7 SDK](https://dotnet.microsoft.com/en-us/download/dotnet/7.0).
10 |
11 | Then you can build native plugins by running the following command:
12 |
13 | ```
14 | dotnet publish -c Release -r win-x64 -p:PublishAot=true
15 | ```
16 |
17 | ### NPlug.SimpleDelay
18 |
19 | This is a port of C/C++ adelay sample from https://github.com/steinbergmedia/vst3_public_sdk/tree/master/samples/vst/adelay/source
20 |
21 | ### NPlug.SimpleProgramChange
22 |
23 | This is a port of C/C++ program change sample from https://github.com/steinbergmedia/vst3_public_sdk/tree/master/samples/vst/programchange/source
24 |
25 | ## Documentation
26 |
27 | You can find more information from NPlug [documentation here](https://github.com/xoofx/NPlug/blob/main/doc/readme.md).
28 |
29 | ## License
30 |
31 | The core part of this software is released under the [BSD-2-Clause license](https://opensource.org/licenses/BSD-2-Clause) but you have also to follow the following VST3 license:
32 |
33 | > **NOTICE**
34 | >
35 | > When you are developing a plugin with NPlug, your plugin needs to comply with the [VST 3 Licensing](https://steinbergmedia.github.io/vst3_dev_portal/pages/VST+3+Licensing/Index.html). If your plugin is distributed, it needs to either be published under:
36 | > - The [Proprietary Steinberg VST 3 license](https://steinbergmedia.github.io/vst3_dev_portal/pages/VST+3+Licensing/What+are+the+licensing+options.html#proprietary-steinberg-vst-3-license) if you want to keep your plugin closed source.
37 | > - The [Open-source GPLv3 license](https://steinbergmedia.github.io/vst3_dev_portal/pages/VST+3+Licensing/What+are+the+licensing+options.html#open-source-gplv3-license) if you want to make your plugin OSS.
38 |
39 | What it means is that you are allowed to modify and redistribute NPlug (according to the `BSD-2-Clause` license) but you need to publish your plugin under the VST3 dual-license.
40 |
41 | ## Author
42 |
43 | Alexandre Mutel aka [xoofx](https://xoofx.github.io).
44 |
45 |
--------------------------------------------------------------------------------