<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Arthur O. Reis</title>
    <description>The latest articles on DEV Community by Arthur O. Reis (@reis0).</description>
    <link>https://dev.to/reis0</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F295172%2Ff793036f-1dca-4ff1-9575-d9ab6cd3ffc8.png</url>
      <title>DEV Community: Arthur O. Reis</title>
      <link>https://dev.to/reis0</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/reis0"/>
    <language>en</language>
    <item>
      <title>Audio plugin development with DPF: first plugin</title>
      <dc:creator>Arthur O. Reis</dc:creator>
      <pubDate>Sat, 18 Jun 2022 14:14:05 +0000</pubDate>
      <link>https://dev.to/reis0/audio-plugin-developmento-with-dpf-first-plugin-1jd0</link>
      <guid>https://dev.to/reis0/audio-plugin-developmento-with-dpf-first-plugin-1jd0</guid>
      <description>&lt;h2&gt;
  
  
  What is DPF?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/DISTRHO/DPF" rel="noopener noreferrer"&gt;DPF&lt;/a&gt;, short name for Distrho Plugin Framework, is a framework for building audio plugins in C++, compared to JUCE is smaller and more "raw", but there's no commercial licensing or limitation, also it supports open formats like LADSPA and LV2. It has support for Linux and Windows, here I will assume you're using Linux, so some commands may differ in Windows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up a DPF project
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Adding DPF to your project
&lt;/h3&gt;

&lt;p&gt;One of the main difficulties I've had with DPF was understanding how to add it to my project, more directly to my git repository, so I'll focus a little more on this, specially for people who are not used to it.&lt;/p&gt;

&lt;p&gt;First you need to create a git project, you can just create it on GitHub or GitLab, or whatever other git hosting website, and clone it, or you can do it directly on your computer (remember to add a remote later). We'll be doing the latter:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; DPFTutorial &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;DPFTutorial
git init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these commands we've created a new folder and initialized git in it, now let's add DPF as a submodule:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git submodule add https://github.com/DISTRHO/DPF dpf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don't know about git submodules I recommend taking your time to read about, It's not complicated, but to resume you're basically adding a git project inside your git project, where you can change commits, branches and other stuff separately.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating the plugins folder
&lt;/h3&gt;

&lt;p&gt;Now we will create the &lt;code&gt;plugins&lt;/code&gt; folder that will contain our plugin(s):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; plugins
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the default folder structure you'll find in DPF projects, I think it is pretty straightforward.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;projectdir/
└── dpf/ (git submodule)
└── plugins/
    └── MyPlugin (not created yet)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating the plugin
&lt;/h2&gt;

&lt;p&gt;Since we now know how to set up the correct environment, let's start with our plugin, it will be the simplest plugin you can build, an amplifier that you can turn gain up or down, since the goal here is on how to use DPF I will not show how to create sophisticated plugins.&lt;/p&gt;

&lt;p&gt;Let's create the folder for the plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; MyAmp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have the following structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DPFTutorial/
└── dpf/ (git submodule)
└── plugins/
    └── MyAmp/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Setting the plugin information
&lt;/h3&gt;

&lt;p&gt;Now we will create the &lt;code&gt;DistrhoPluginInfo.h&lt;/code&gt; file in our plugin folder, in this file resides some data about the plugin, like name, how many inputs and outputs, if it receives midi, etc. This information is set by macros, you can find more about them &lt;a href="https://distrho.github.io/DPF/group__PluginMacros.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED
#define DISTRHO_PLUGIN_INFO_H_INCLUDED
&lt;/span&gt;
&lt;span class="cp"&gt;#define DISTRHO_PLUGIN_NAME  "MyAmp"
#define DISTRHO_PLUGIN_URI   "https://github.com/REIS0/DPFTutorial"
&lt;/span&gt;
&lt;span class="cp"&gt;#define DISTRHO_PLUGIN_NUM_INPUTS   1
#define DISTRHO_PLUGIN_NUM_OUTPUTS  1
#define DISTRHO_PLUGIN_IS_RT_SAFE   1
&lt;/span&gt;
&lt;span class="cp"&gt;#endif
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this we've told DPF information about our plugin &lt;code&gt;DISTRHO_PLUGIN_NAME&lt;/code&gt; is our plugin's name, &lt;code&gt;DISTRHO_PLUGIN_URI&lt;/code&gt; for our plugin URI (which I won't go in depth of what a URI is, but you can take a &lt;a href="https://wikipedia.org/wiki/URI" rel="noopener noreferrer"&gt;read&lt;/a&gt;), you can just use your git repository URL, &lt;code&gt;DISTRHO_PLUGIN_NUM_INPUTS&lt;/code&gt; sets how many inputs our plugin will have, &lt;code&gt;DISTHRO_PLUGIN_NUM_OUTPUTS&lt;/code&gt; sets how many outputs, and &lt;code&gt;DISTHRO_PLUGIN_IS_RT_SAFE&lt;/code&gt; says if out plugin is safe to use in a real time context, since our plugin is really simple we set this to &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding parameters
&lt;/h3&gt;

&lt;p&gt;Now we will set the parameters our plugin will have, for now these are only declarations, later we are going to set more information like values, their name in the GUI, etc. Add them to &lt;code&gt;DistrhoPluginInfo.h&lt;/code&gt;, after the plugin information and just before the &lt;code&gt;#endif&lt;/code&gt; section:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;

&lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;Parameters&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;kGain&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;kParameterCount&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="cp"&gt;#endif
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The parameters are one &lt;code&gt;enum&lt;/code&gt; structure, &lt;code&gt;kGain&lt;/code&gt; is our only parameter, &lt;code&gt;kParameterCount&lt;/code&gt; is the number of parameters we have (for those who don't know how &lt;code&gt;enum&lt;/code&gt; works, basically each item corresponds to a number, so &lt;code&gt;kGain&lt;/code&gt; will be 0 and &lt;code&gt;kParameterCount&lt;/code&gt; will be 1, notice that 1 is the number of parameters), this will be important later when we create our plugin file.&lt;/p&gt;

&lt;h3&gt;
  
  
  The plugin itself
&lt;/h3&gt;

&lt;p&gt;Now let's create our plugin, first create &lt;code&gt;MyAmp.cpp&lt;/code&gt; file in the same folder, then we will add some code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt; &lt;span class="cpf"&gt;"DistrhoPlugin.hpp"&lt;/span&gt;&lt;span class="cp"&gt;
&lt;/span&gt;
&lt;span class="n"&gt;START_NAMESPACE_DISTRHO&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyAmp&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Plugin&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;public:&lt;/span&gt;
        &lt;span class="n"&gt;MyAmp&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Plugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kParameterCount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;gain&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
        &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;gain&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="n"&gt;DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MyAmp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;Plugin&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="nf"&gt;createPlugin&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;MyAmp&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;END_NAMESPACE_DISTRHO&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the first line we include the &lt;code&gt;DistrhoPlugin.hpp&lt;/code&gt; to import the functions we will need, the second and the end &lt;code&gt;START_NAMESPACE_DISTRHO&lt;/code&gt; and &lt;code&gt;END_NAMESPACE_DISTRHO&lt;/code&gt;, as the name suggests it sets the namespace for the functions, if you don't know about namespaces there's a ton of resources on the internet to read about, for now just remember we need to add them to our code. After that we create our &lt;code&gt;MyAmp&lt;/code&gt; class, as you can see is the name of our plugin, is not necessary to have the same name but is a good practice, so I highly recommend using it, then we need to inherit from the &lt;code&gt;Plugin&lt;/code&gt; class, with this we set that our class will be a plugin type class, and we add a constructor for &lt;code&gt;Plugin&lt;/code&gt; with the parameters: number of parameters in the plugin, number of programs in the plugin and number of states in the plugin, for this plugin we will set only the number of parameters, using the &lt;code&gt;kParameterCount&lt;/code&gt; we explained earlier. Finally we set the initial value for the &lt;code&gt;gain&lt;/code&gt; variable, which is where we will read and store the values for &lt;code&gt;kGain&lt;/code&gt; parameter (so with this logic, we can easily assume that for each parameter we'll need a variable in our plugin class).&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding some "metadata" information
&lt;/h3&gt;

&lt;p&gt;Now let's add some information about our plugin, this information will be more like metadata, author, licensing, etc:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;    &lt;span class="c1"&gt;// PUBLIC SPACE&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;

        &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;getLabel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"MyAmp"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;getDescription&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"Simple amp plugin."&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;getMaker&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"REIS0"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;char&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;getLicense&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;"MIT"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="kt"&gt;uint32_t&lt;/span&gt; &lt;span class="nf"&gt;getVersion&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;d_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="kt"&gt;int64_t&lt;/span&gt; &lt;span class="nf"&gt;getUniqueId&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;d_cconst&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sc"&gt;'M'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sc"&gt;'A'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sc"&gt;'D'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="sc"&gt;'T'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The functions speak for themselves, but we will have a fast look at them: &lt;code&gt;getLabel()&lt;/code&gt; is for the plugin label, almost all the times you will put the plugin name, &lt;code&gt;getDescription()&lt;/code&gt; to describe the plugin, &lt;code&gt;getMaker()&lt;/code&gt; who made the plugin, here is my username, but you should set your own, &lt;code&gt;getLicense()&lt;/code&gt; is for the license, I'm using MIT here but you can choose any you prefer, &lt;code&gt;getVersion()&lt;/code&gt; for the plugin version, so if is 1.0.0 we will set as &lt;code&gt;d_version(1,0,0)&lt;/code&gt;, &lt;code&gt;getUniqueId()&lt;/code&gt; sets the plugin ID, this is used by the host the know your plugin and to not cause conflicts between other ones, here I've set &lt;code&gt;'M','A','D','T'&lt;/code&gt;, which I've taken from &lt;strong&gt;M&lt;/strong&gt;y &lt;strong&gt;A&lt;/strong&gt;mp &lt;strong&gt;D&lt;/strong&gt;PF &lt;strong&gt;T&lt;/strong&gt;utorial, personally I prefer to set it related to the plugin name, but is up to you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parameters
&lt;/h3&gt;

&lt;p&gt;Let's handle our parameters now, first we need to start the parameters we set earlier, is not complicate, add this function below the metadata:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// SOME METADATA&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;initParameter&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint32_t&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Parameter&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;parameter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;kGain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;parameter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Gain"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="n"&gt;parameter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;symbol&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"gain"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="n"&gt;parameter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ranges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;def&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="n"&gt;parameter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ranges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;min&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="n"&gt;parameter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ranges&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="nl"&gt;default:&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we use a &lt;code&gt;switch&lt;/code&gt; to match the parameters, if we had more than one parameter than we would need to add more cases, since we only have &lt;code&gt;kGain&lt;/code&gt; there's no need to. Let's pass through these stuff: &lt;code&gt;parameter.name&lt;/code&gt; sets the name for the parameter, so when you open the plugin you'll see "Gain" on it, then we have &lt;code&gt;parameter.symbol&lt;/code&gt;, we can compare this to a parameter id, so it needs to be unique, and you can't repeat for other parameters, &lt;code&gt;parameter.ranges&lt;/code&gt; sets the values for our parameter, &lt;code&gt;def&lt;/code&gt; is the default value when we open the plugin for the first time, &lt;code&gt;min&lt;/code&gt; is minimum possible value, &lt;code&gt;max&lt;/code&gt; is the maximum possible value.&lt;/p&gt;

&lt;p&gt;For now, we only initialized the parameters and need a way to handle them, for this purpose we'll add two new functions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="nf"&gt;getParameterValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint32_t&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;kGain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;gain&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;default:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;setParameterValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint32_t&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;kGain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="n"&gt;gain&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nl"&gt;default:&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first function is a way for the plugin to know the actual value we have stored in out parameter, now we have only one parameter &lt;code&gt;kGain&lt;/code&gt;, which maps to our &lt;code&gt;gain&lt;/code&gt; variable, this logic is repeatable for any number of parameters. The second function is for handling when the user changes the parameter value in the plugin UI (for now we'll be using the generic UI provided by the host, but in the future we can add a custom one), to store the new value we just update our variable that corresponds to the changed parameter, in this case again &lt;code&gt;gain&lt;/code&gt; is the variable mapped to the &lt;code&gt;kGain&lt;/code&gt; parameter.&lt;/p&gt;

&lt;p&gt;Now that we have everything set, we can finally write our processing logic, since the focus is working with a DPF setup I won't be going deeper into the audio processing part, also this is just an amplifier, so it will be very simple and there isn't much to explain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight cpp"&gt;&lt;code&gt;&lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;outputs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;uint32_t&lt;/span&gt; &lt;span class="n"&gt;frames&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="kt"&gt;float&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="k"&gt;const&lt;/span&gt; &lt;span class="n"&gt;out&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;outputs&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;uint32_t&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;frames&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;out&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;gain&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First we assign the inputs and outputs, since we only have one input and one output as we set in &lt;code&gt;DistrhoPluginInfo.h&lt;/code&gt; we just get the &lt;code&gt;0&lt;/code&gt; position, but if we had two, we'll need to map the &lt;code&gt;0&lt;/code&gt; and &lt;code&gt;1&lt;/code&gt; positions, and it goes as we increase the inputs and outputs number. Now we'll go through our &lt;code&gt;frames&lt;/code&gt;, also known as samples (if you don't really know what I mean take a look &lt;a href="https://www.youtube.com/playlist?list=PLbqhA-NKGP6B6V_AiS-jbvSzdd7nbwwCw" rel="noopener noreferrer"&gt;here&lt;/a&gt;), and make the processing, since it's just an amplifier this part is very simple.&lt;/p&gt;

&lt;h3&gt;
  
  
  Makefiles
&lt;/h3&gt;

&lt;p&gt;Now that we have our plugin class completed, we need to build it (recently cmake support was added to DPF, but since I don't know how to use cmake at all it will not be covered here), for this purpose we'll write two Makefiles, if you don't know what Makefiles are you can just search for it and find some good explanations and guides, the first Makefile will be in our plugin folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DPFTutorial/
└── dpf/ (git submodule)
└── plugins/
    └── MyAmp/
        └── DistrhoPluginInfo.h
        └── MyAmp.cpp
        └── Makefile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/make -f
# Makefile for DISTRHO Plugins #
# ---------------------------- #
# Created by falkTX
#
# Modified by REIS0
&lt;/span&gt;
&lt;span class="nv"&gt;VST2&lt;/span&gt; &lt;span class="o"&gt;?=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;
&lt;span class="nv"&gt;LV2&lt;/span&gt; &lt;span class="o"&gt;?=&lt;/span&gt; &lt;span class="nb"&gt;true&lt;/span&gt;

&lt;span class="c"&gt;# --------------------------------------------------------------
# Project name, used for binaries
&lt;/span&gt;
&lt;span class="nv"&gt;NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; MyAmp

&lt;span class="c"&gt;# --------------------------------------------------------------
# Files to build
&lt;/span&gt;
&lt;span class="nv"&gt;FILES_DSP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; MyAmp.cpp

&lt;span class="c"&gt;# --------------------------------------------------------------
# Do some magic
&lt;/span&gt;
&lt;span class="k"&gt;include&lt;/span&gt;&lt;span class="sx"&gt; ../../dpf/Makefile.plugins.mk&lt;/span&gt;

&lt;span class="c"&gt;# --------------------------------------------------------------
# VST2 and LV2 targets
&lt;/span&gt;
&lt;span class="k"&gt;ifeq&lt;/span&gt; &lt;span class="nv"&gt;($(VST2), true)&lt;/span&gt;
&lt;span class="nv"&gt;TARGETS&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; vst
&lt;span class="k"&gt;endif&lt;/span&gt;

&lt;span class="k"&gt;ifeq&lt;/span&gt; &lt;span class="nv"&gt;($(LV2), true)&lt;/span&gt;
&lt;span class="k"&gt;ifeq&lt;/span&gt; &lt;span class="nv"&gt;($(HAVE_DGL),true)&lt;/span&gt;
&lt;span class="nv"&gt;TARGETS&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; lv2_sep
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="nv"&gt;TARGETS&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; lv2_dsp
&lt;span class="k"&gt;endif&lt;/span&gt;
&lt;span class="k"&gt;endif&lt;/span&gt;

&lt;span class="nl"&gt;all&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;$(TARGETS)&lt;/span&gt;

&lt;span class="c"&gt;# --------------------------------------------------------------
&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're not used to Makefiles it might look a little complicated, but don't worry, you can just copy this one and change it according to your needs, so here what we do in it: first we set what plugin formats we'll be compiling it to, in this case LV2 and VST (there's also the option as a JACK Standalone application in DPF), then we set the name of our plugin, the files needed to compile, include the DPF stuff, and then some instructions for the compilation.&lt;/p&gt;

&lt;p&gt;The second Makefile we'll in our project root folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DPFTutorial/
└── dpf/ (git submodule)
└── plugins/
    └── MyAmp/
└── Makefile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight make"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/usr/bin/make -f
# Makefile for DISTRHO Plugins #
# ---------------------------- #
# Created by falkTX
#
# Modified by REIS0
&lt;/span&gt;
&lt;span class="nv"&gt;PLUGIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;MyAmp

&lt;span class="k"&gt;include&lt;/span&gt;&lt;span class="sx"&gt; dpf/Makefile.base.mk&lt;/span&gt;

&lt;span class="nl"&gt;all&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;dgl plugins gen&lt;/span&gt;

&lt;span class="c"&gt;# --------------------------------------------------------------
&lt;/span&gt;
&lt;span class="nl"&gt;dgl&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="k"&gt;ifeq&lt;/span&gt; &lt;span class="nv"&gt;($(HAVE_OPENGL),true)&lt;/span&gt;
 &lt;span class="err"&gt;$(MAKE)&lt;/span&gt; &lt;span class="err"&gt;-C&lt;/span&gt; &lt;span class="err"&gt;dpf/dgl&lt;/span&gt; &lt;span class="err"&gt;opengl&lt;/span&gt;
&lt;span class="k"&gt;endif&lt;/span&gt;

&lt;span class="nl"&gt;plugins&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;dgl&lt;/span&gt;
 &lt;span class="err"&gt;$(MAKE)&lt;/span&gt; &lt;span class="err"&gt;all&lt;/span&gt; &lt;span class="err"&gt;-C&lt;/span&gt; &lt;span class="err"&gt;plugins/$(PLUGIN)&lt;/span&gt;

&lt;span class="k"&gt;ifneq&lt;/span&gt; &lt;span class="nv"&gt;($(CROSS_COMPILING),true)&lt;/span&gt;
&lt;span class="nl"&gt;gen&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;plugins dpf/utils/lv2_ttl_generator&lt;/span&gt;
 &lt;span class="err"&gt;@$(CURDIR)/dpf/utils/generate-ttl.sh&lt;/span&gt;
&lt;span class="k"&gt;ifeq&lt;/span&gt; &lt;span class="nv"&gt;($(MACOS),true)&lt;/span&gt;
 &lt;span class="err"&gt;@$(CURDIR)/dpf/utils/generate-vst-bundles.sh&lt;/span&gt;
&lt;span class="k"&gt;endif&lt;/span&gt;

&lt;span class="nl"&gt;dpf/utils/lv2_ttl_generator&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
 &lt;span class="err"&gt;$(MAKE)&lt;/span&gt; &lt;span class="err"&gt;-C&lt;/span&gt; &lt;span class="err"&gt;dpf/utils/lv2-ttl-generator&lt;/span&gt;
&lt;span class="k"&gt;else&lt;/span&gt;
&lt;span class="nl"&gt;gen&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
&lt;span class="k"&gt;endif&lt;/span&gt;

&lt;span class="c"&gt;# --------------------------------------------------------------
&lt;/span&gt;
&lt;span class="nl"&gt;clean&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
 &lt;span class="err"&gt;$(MAKE)&lt;/span&gt; &lt;span class="err"&gt;clean&lt;/span&gt; &lt;span class="err"&gt;-C&lt;/span&gt; &lt;span class="err"&gt;dpf/dgl&lt;/span&gt;
 &lt;span class="err"&gt;$(MAKE)&lt;/span&gt; &lt;span class="err"&gt;clean&lt;/span&gt; &lt;span class="err"&gt;-C&lt;/span&gt; &lt;span class="err"&gt;dpf/utils/lv2-ttl-generator&lt;/span&gt;
 &lt;span class="err"&gt;$(MAKE)&lt;/span&gt; &lt;span class="err"&gt;clean&lt;/span&gt; &lt;span class="err"&gt;-C&lt;/span&gt; &lt;span class="err"&gt;plugins/$(PLUGIN)&lt;/span&gt;
 &lt;span class="err"&gt;rm&lt;/span&gt; &lt;span class="err"&gt;-rf&lt;/span&gt; &lt;span class="err"&gt;bin&lt;/span&gt; &lt;span class="err"&gt;build&lt;/span&gt;

&lt;span class="c"&gt;# --------------------------------------------------------------
&lt;/span&gt;
&lt;span class="nl"&gt;.PHONY&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;plugins&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this one the only thing we need to change is the &lt;code&gt;PLUGIN&lt;/code&gt; variable, everything else you can just leave it there, or edit if you know what you're doing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Compiling the plugin
&lt;/h3&gt;

&lt;p&gt;With everything setup we can finally compile and test our plugin, just go to the root project folder and run &lt;code&gt;make&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;DPFTutorial/plugins/MyAmp&lt;span class="nv"&gt;$:&lt;/span&gt; make
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything went well, it should generate a &lt;code&gt;bin&lt;/code&gt; folder with an LV2 and VST plugin inside, LV2 is a folder and VST is just a file. Now just load it in a DAW or a host like Carla, and test if it works.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;And with this we finished the first DPF guide, while this was mostly a setup tutorial, which it is in my opinion the hardest part to get into when someone first encounter the DPF framework, so far I hope I've helped in any way. Maybe I'll try to make a UI focused guide in the future. You can find the whole project in the &lt;a href="https://github.com/REIS0/DPFTutorial" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>audioplugin</category>
      <category>dpf</category>
      <category>audio</category>
      <category>cpp</category>
    </item>
  </channel>
</rss>
