<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>Coherent Musings - Posts</title>
    <link rel="self" type="application/atom+xml" href="https://sanchayanmaity.net/posts/atom.xml"/>
    <link rel="alternate" type="text/html" href="https://sanchayanmaity.net/posts/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2025-01-04T00:00:00+00:00</updated>
    <id>https://sanchayanmaity.net/posts/atom.xml</id>
    <entry xml:lang="en">
        <title>Getting rid of LaTeX</title>
        <published>2025-01-04T00:00:00+00:00</published>
        <updated>2025-01-04T00:00:00+00:00</updated>
        
        <author>
          <name>Sanchayan Maity</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://sanchayanmaity.net/posts/getting-rid-of-latex/"/>
        <id>https://sanchayanmaity.net/posts/getting-rid-of-latex/</id>
        
        <content type="html" xml:base="https://sanchayanmaity.net/posts/getting-rid-of-latex/">&lt;p&gt;Have been using &lt;a rel=&quot;external&quot; href=&quot;https://pandoc.org/&quot;&gt;Pandoc&lt;/a&gt; for a long time now to make presentations by using the default beamer template. Nothing fancy, as it&#39;s not something to be spending a lot of time on. Wanted to keep writing simple Markdown but now that Pandoc supports using &lt;a rel=&quot;external&quot; href=&quot;https://typst.app/&quot;&gt;Typst&lt;/a&gt; as the PDF engine, getting rid of some 2.5 GB of LaTeX packages installed on the system is easier than ever.&lt;/p&gt;
&lt;p&gt;Pandoc keeps a store of all the default templates it uses for different outputs, and one can tell Pandoc to show the default template for any given format, like below.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;pandoc&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -D&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; typst&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; template.typ&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then adding this &lt;a rel=&quot;external&quot; href=&quot;https://typst.app/universe/package/diatypst&quot;&gt;diatypst&lt;/a&gt; template to the preceding, gets pretty close to the earlier setup. Specifying an engine and a Typst template to Pandoc can be done like below.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;--pdf-engine&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;typst&lt;/span&gt;&lt;span&gt; --template&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;template.typ&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Still need to figure out a few things like using different colours for links/URLs but good enough for now. Believe one can use raw Typst in the markdown for that. A sample setup using what was just described can be seen &lt;a rel=&quot;external&quot; href=&quot;https://git.sanchayanmaity.net/sanchayanmaity/presentations/src/branch/master/monads&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Notes from GStreamer spring hackfest of 2024</title>
        <published>2024-07-30T00:00:00+00:00</published>
        <updated>2024-07-30T00:00:00+00:00</updated>
        
        <author>
          <name>Sanchayan Maity</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://sanchayanmaity.net/posts/gstreamer-hackfest-2024/"/>
        <id>https://sanchayanmaity.net/posts/gstreamer-hackfest-2024/</id>
        
        <content type="html" xml:base="https://sanchayanmaity.net/posts/gstreamer-hackfest-2024/">&lt;p&gt;Some time has passed since the GStreamer spring hackfest took place in Thessaloniki, Greece in the month of May. Second time attending the GStreamer hackfest and thought about summarizing some of my thoughts this time around.&lt;/p&gt;
&lt;h2 id=&quot;thanks&quot;&gt;Thanks&lt;/h2&gt;
&lt;p&gt;Before getting into the details, want to send out a thank you to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The GStreamer foundation for sponsoring the event as a whole&lt;/li&gt;
&lt;li&gt;Sebastian, Vivia and Jordan for making all the arrangements&lt;/li&gt;
&lt;li&gt;Asymptotic, for sponsoring my presence at the event&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;the-event&quot;&gt;The event&lt;/h2&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://social.cologne/@francisv/112518409917632684&quot;&gt;At the hackfest&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It was good to see some familiar faces at the event, folks whom I had met at the previous hackfest and conference. Also nice when you finally meet people you have only conversed with online and get to put a face on the online persona you have been conversing with.&lt;/p&gt;
&lt;h2 id=&quot;work&quot;&gt;Work&lt;/h2&gt;
&lt;p&gt;Originally the plan was to work on adding stream multiplexing support to &lt;a rel=&quot;external&quot; href=&quot;https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/tree/main/net/quinn/src?ref_type=heads&quot;&gt;QUIC&lt;/a&gt; elements. However, missed pushing some of the work to GitLab which was on desktop and decided to work on that later.&lt;/p&gt;
&lt;h3 id=&quot;http-live-streaming-hls&quot;&gt;HTTP Live Streaming (HLS)&lt;/h3&gt;
&lt;p&gt;A merge request for adding &lt;a rel=&quot;external&quot; href=&quot;https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1515&quot;&gt;multi-variant playlist support with HLS&lt;/a&gt; has been pending review for a while. One of the features missing from that merge request was support for codec string generation when using MPEG-TS with H-264 and H-265. Decided to work on that.&lt;/p&gt;
&lt;p&gt;H-264 or H-265 has what are known as &lt;code&gt;stream-formats&lt;/code&gt;. H-264 or H-265 can be stream oriented or packet oriented. In the case of former, &lt;code&gt;stream-format&lt;/code&gt; is said to be &lt;code&gt;byte-stream&lt;/code&gt;, while in the case of latter, &lt;code&gt;stream-format&lt;/code&gt; is said to be &lt;code&gt;avc&lt;/code&gt;. For &lt;code&gt;byte-stream&lt;/code&gt;, the required parameter sets are sent in-band with the video, but for &lt;code&gt;avc&lt;/code&gt; in GStreamer, the video metadata is conveyed via an additional caps field named &lt;code&gt;codec_data&lt;/code&gt; which can be considered as out-of-band. &lt;code&gt;codec_data&lt;/code&gt; is only present when the video is packet oriented, that&#39;s when &lt;code&gt;stream-format&lt;/code&gt; is &lt;code&gt;avc&lt;/code&gt;, this value represents an &lt;code&gt;AVCDecoderConfigurationRecord&lt;/code&gt; structure.&lt;/p&gt;
&lt;p&gt;GStreamer already has helper functions in codec utilities which can provide information like &lt;code&gt;profile-level&lt;/code&gt; which are required for constructing codec strings. However, these helper functions require the existence of &lt;code&gt;codec_data&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;When using MPEG-TS as the container, the only possible &lt;code&gt;stream-format&lt;/code&gt; is &lt;code&gt;byte-stream&lt;/code&gt; with H-264 or H-265. In this case, one needs to parse the in-band information for getting information like &lt;code&gt;profile-level&lt;/code&gt; or other video metadata. In Rust, there is the &lt;a rel=&quot;external&quot; href=&quot;https://docs.rs/cros-codecs/latest/cros_codecs/codec/index.html&quot;&gt;&lt;code&gt;cros-codecs&lt;/code&gt;&lt;/a&gt; crate which has a parser module. Using this, it was easy to parse the in-band data and then generate the codec string required for HLS playlist.&lt;/p&gt;
&lt;h3 id=&quot;threadshare&quot;&gt;Threadshare&lt;/h3&gt;
&lt;p&gt;Before the hackfest, had spend some time on understanding the &lt;a rel=&quot;external&quot; href=&quot;https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/tree/main/generic/threadshare/src?ref_type=heads&quot;&gt;&lt;code&gt;threadshare&lt;/code&gt;&lt;/a&gt; elements. Met François Laignel at the hackfest who helped with clearing doubts I had with how some of the code was laid out in &lt;code&gt;threadshare&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you are interested in understanding about what makes the &lt;code&gt;threadshare&lt;/code&gt; elements different, highly recommend going through the blog post &lt;a rel=&quot;external&quot; href=&quot;https://coaxion.net/blog/2018/04/improving-gstreamer-performance-on-a-high-number-of-network-streams-by-sharing-threads-between-elements-with-rusts-tokio-crate/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There was some &lt;code&gt;end-of-stream&lt;/code&gt; handling missing with the &lt;code&gt;threadshare&lt;/code&gt;, &lt;code&gt;tcpclientsrc&lt;/code&gt; and &lt;code&gt;udpsrc&lt;/code&gt; elements. Spend some time working on adding support for that, which has now been &lt;a rel=&quot;external&quot; href=&quot;https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/1581#d18be81ee1a92c24cf3786f98c51bc93bd1ce661&quot;&gt;merged&lt;/a&gt; upstream.&lt;/p&gt;
&lt;h2 id=&quot;play&quot;&gt;Play&lt;/h2&gt;
&lt;p&gt;After the three days of hackfest, a day trip was planned to the Palace of Aigai.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://social.cologne/@francisv/112530301636663783&quot;&gt;GStreamer hackers &amp;amp; co. exploring the Palace of Aigai&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;All in all, this hackfest turned out to be a productive and fun filled hackfest. Also, have to add that Greek cuisine is excellent and look forward to the next hackfest and visiting Thessaloniki/Greece again.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Writing a simple PipeWire parametric equalizer module</title>
        <published>2024-05-07T00:00:00+00:00</published>
        <updated>2024-05-07T00:00:00+00:00</updated>
        
        <author>
          <name>Sanchayan Maity</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://sanchayanmaity.net/posts/pipewire-parametric-autoeq/"/>
        <id>https://sanchayanmaity.net/posts/pipewire-parametric-autoeq/</id>
        
        <content type="html" xml:base="https://sanchayanmaity.net/posts/pipewire-parametric-autoeq/">&lt;h1 id=&quot;motivation&quot;&gt;Motivation&lt;/h1&gt;
&lt;p&gt;When using headphones or in-ear monitors (IEMs), one might want to EQ their headphones or IEMs. Equalization or EQ is the process of adjusting the volume of different frequency bands in an audio signal. Some popular EQ software are EasyEffects on Linux and Equalizer APO on Windows. PipeWire supports EQ via the &lt;a rel=&quot;external&quot; href=&quot;https://docs.pipewire.org/page_module_filter_chain.html&quot;&gt;filter-chain&lt;/a&gt; module.&lt;/p&gt;
&lt;p&gt;For an understanding of EQ, following resources might help.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://youtu.be/FRm9qTmQHKo?si=BFi0IH_XiCz1AxWa&quot;&gt;The Headphone Show - EQ Basics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://www.youtube.com/watch?v=FD_s2s8Mw9k&amp;amp;t=0s&quot;&gt;The Headphone Show - The Limits of EQ&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;external&quot; href=&quot;https://crinacle.com/2020/04/08/graphs-101-how-to-read-headphone-measurements/&quot;&gt;Graphs 101 - How to Read Headphone Measurements&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The basic idea is that there are some “standard” frequency response curves that might sound good to different individuals, and knowing the frequency response characteristics of a specific headphone/IEM model, you can apply a set of filters via an equalizer to achieve something close to the “standard” frequency response curve that sounds good to you.&lt;/p&gt;
&lt;p&gt;Websites like &lt;a rel=&quot;external&quot; href=&quot;http://squig.link&quot;&gt;Squig&lt;/a&gt; or &lt;a rel=&quot;external&quot; href=&quot;https://www.autoeq.app/&quot;&gt;autoeq.app&lt;/a&gt; generate a file for parametric equalization for a given target, but this isn&#39;t a format that can be directly given to filter chain module. Squig is also useful for evaluating the frequency response curves of various in-ear monitors and headphones when making buying decisions.&lt;/p&gt;
&lt;p&gt;An example of Parametric EQ generated from either AutoEQ or Squig looks like below.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Preamp: -6.8 dB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filter 1: ON PK Fc 20 Hz Gain -1.3 dB Q 2.000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filter 2: ON PK Fc 31 Hz Gain -7.0 dB Q 0.500&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filter 3: ON PK Fc 36 Hz Gain 0.7 dB Q 2.000&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filter 4: ON PK Fc 88 Hz Gain -0.4 dB Q 2.000&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;Fc&lt;/code&gt; is the frequency, &lt;code&gt;Gain&lt;/code&gt; is the amount with which the signal gets boosted or attenuated around that frequency. &lt;code&gt;Q&lt;/code&gt; factor controls the bandwidth around the frequency point. To be more precise, &lt;code&gt;Q&lt;/code&gt; is the ratio of center frequency to bandwidth. If the center frequency is fixed, the bandwidth is inversely proportional to Q implying that as one raises the Q, the bandwidth is narrowed. Q is by far the most useful tool a parametric EQ offers, allowing one to attenuate or boost a narrow or wide range of frequencies within each EQ band.&lt;/p&gt;
&lt;p&gt;If one wants to build a better intuition for this, playing around with the filter type and parameters &lt;a rel=&quot;external&quot; href=&quot;https://arachnoid.com/BiQuadDesigner/index.html&quot;&gt;here&lt;/a&gt;, and seeing the effects on the frequency response helps. This linked article also goes into the basics of filters.&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://github.com/wwmm/easyeffects&quot;&gt;&lt;em&gt;&lt;strong&gt;EasyEffects&lt;/strong&gt;&lt;/em&gt;&lt;/a&gt; allows importing such a file via it’s &lt;code&gt;Import APO&lt;/code&gt; option, however, one might want to use an EQ input like this directly in PipeWire without having to resort to additional software like EasyEffects. However, during the course of testing, trying out multiple EQ is definitely much easier with EasyEffects GUI.&lt;/p&gt;
&lt;p&gt;Now, this needs to be converted manually into something which &lt;a rel=&quot;external&quot; href=&quot;https://docs.pipewire.org/page_module_filter_chain.html&quot;&gt;filter-chain&lt;/a&gt; module can accept.&lt;/p&gt;
&lt;p&gt;To simplify this, a simple PipeWire module is implemented which reads a parametric EQ text file like preceding and loads filter chain module while translating the inputs from the text file to what the filter chain module expects.&lt;/p&gt;
&lt;p&gt;Before writing the PipeWire module, generate such a parametric equalizer file for a selected headphone and target using &lt;a rel=&quot;external&quot; href=&quot;https://github.com/jaakkopasanen/AutoEq&quot;&gt;AutoEq&lt;/a&gt;. While the web interface at &lt;a rel=&quot;external&quot; href=&quot;https://autoeq.app/&quot;&gt;autoeq.app&lt;/a&gt; can be used, below section covers how to do this from the command line.&lt;/p&gt;
&lt;h1 id=&quot;automatic-headphone-equalization&quot;&gt;Automatic headphone equalization&lt;/h1&gt;
&lt;p&gt;Installation instructions for AutoEq can be found &lt;a rel=&quot;external&quot; href=&quot;https://github.com/jaakkopasanen/AutoEq?tab=readme-ov-file#installing&quot;&gt;here&lt;/a&gt;. Take the example of Beyerdynamic DT1990 headphone and Diffuse Field 5128 target. For brevity sake, what target curve to select and why isn&#39;t covered here.&lt;/p&gt;
&lt;p&gt;Measurements can be found in &lt;a rel=&quot;external&quot; href=&quot;https://github.com/jaakkopasanen/AutoEq/tree/master/measurements&quot;&gt;measurements&lt;/a&gt; directory and targets can be found in &lt;a rel=&quot;external&quot; href=&quot;https://github.com/jaakkopasanen/AutoEq/tree/master/targets&quot;&gt;targets&lt;/a&gt; directory. Note that if measurements aren&#39;t available for the selected headphone, earphone, or in-ear monitor, AutoEq can&#39;t be used. &lt;code&gt;oratory1990&lt;/code&gt; and &lt;code&gt;crinacle&lt;/code&gt; are well known folks in the audiophile community who have provided measurements for various popular headphones and in-ears. &lt;code&gt;oratory1990&lt;/code&gt;&#39;s measurements are considered below.&lt;/p&gt;
&lt;p&gt;Create a results directory &lt;code&gt;dt1990-results&lt;/code&gt; and then execute the below command.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;python&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -m&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; autoeq&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; --input-file=&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;measurements/oratory1990/data/over-ear/Beyerdynamic DT 1990 (balanced earpads).csv&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; --output-dir=&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;dt1990-results&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; --target=&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;targets/Diffuse field 5128.csv&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; --parametric-eq --fs=44100,48000&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The results directory &lt;code&gt;dt1990-results&lt;/code&gt; has the below output.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;Beyerdynamic&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; DT&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 1990&lt;/span&gt;&lt;span&gt; (balanced&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; earpads&lt;/span&gt;&lt;span&gt;).csv&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;Beyerdynamic&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; DT&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 1990&lt;/span&gt;&lt;span&gt; (balanced&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; earpads&lt;/span&gt;&lt;span&gt;).png&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;Beyerdynamic&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; DT&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 1990&lt;/span&gt;&lt;span&gt; (balanced&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; earpads&lt;/span&gt;&lt;span&gt;) GraphicEQ.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;Beyerdynamic&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; DT&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 1990&lt;/span&gt;&lt;span&gt; (balanced&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; earpads&lt;/span&gt;&lt;span&gt;) ParametricEQ.txt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;README.md&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;Beyerdynamic DT 1990 (balanced earpads) ParametricEQ.txt&lt;/code&gt; file has the parametric equalizer configuration needed which can be given to the PipeWire module discussed next. &lt;code&gt;README&lt;/code&gt; has some information and recommendation.&lt;/p&gt;
&lt;p&gt;Similar process can be followed for in-ear monitors as well.&lt;/p&gt;
&lt;h1 id=&quot;module&quot;&gt;Module&lt;/h1&gt;
&lt;p&gt;A module is a client in a shared library &lt;code&gt;.so&lt;/code&gt; file which shares a PipeWire context with the loading entity. PipeWire context is an object  which manages all locally available resources. See &lt;a rel=&quot;external&quot; href=&quot;https://docs.pipewire.org/group__pw__context.html#details&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A module is loaded when it&#39;s listed in a PipeWire configuration file. Module&#39;s entry point is the &lt;code&gt;pipewire__module_init&lt;/code&gt; function.&lt;/p&gt;
&lt;h1 id=&quot;writing-the-module&quot;&gt;Writing the module&lt;/h1&gt;
&lt;p&gt;A PipeWire module needs to go into &lt;code&gt;src/modules&lt;/code&gt; directory. The file is named &lt;code&gt;module-parametric-equalizer.c&lt;/code&gt; and starts with the &lt;code&gt;pipewire__module_init&lt;/code&gt; function.&lt;/p&gt;
&lt;p&gt;This module primarily has to two tasks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Parse the provided equalizer configuration into what &lt;code&gt;filter-chain&lt;/code&gt; module accepts&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Load the &lt;code&gt;filter-chain&lt;/code&gt; module with these arguments&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The focus is on these two tasks and ignore rest of the ceremony around writing the module.&lt;/p&gt;
&lt;h1 id=&quot;parsing-parametric-equalizer-configuration&quot;&gt;Parsing parametric equalizer configuration&lt;/h1&gt;
&lt;p&gt;Below is the parametric equalizer configuration that was generated in the second section of this post. This configuration is converted to match the module args.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Preamp: -6.0 dB&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filter 1: ON LSC Fc 105 Hz Gain -5.2 dB Q 0.70&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filter 2: ON PK Fc 206 Hz Gain -5.3 dB Q 0.51&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filter 3: ON PK Fc 4532 Hz Gain 5.5 dB Q 0.41&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filter 4: ON PK Fc 791 Hz Gain 2.0 dB Q 1.43&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filter 5: ON PK Fc 6829 Hz Gain -3.8 dB Q 2.04&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filter 6: ON HSC Fc 10000 Hz Gain 3.1 dB Q 0.70&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filter 7: ON PK Fc 8944 Hz Gain -1.4 dB Q 2.88&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filter 8: ON PK Fc 3751 Hz Gain -1.6 dB Q 5.97&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filter 9: ON PK Fc 4458 Hz Gain 1.5 dB Q 6.00&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;Filter 10: ON PK Fc 39 Hz Gain -0.2 dB Q 1.88&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For every line read, a node entry like below is generated.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    type  = builtin&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    name  = eq_band_1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    label = bq_low/highshelf/peaking&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    control = { &amp;quot;Freq&amp;quot; = Fc &amp;quot;Q&amp;quot; = Q &amp;quot;Gain&amp;quot; = Gain }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;PipeWire repository contains a filter chain configuration &lt;a rel=&quot;external&quot; href=&quot;https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/master/src/daemon/filter-chain/sink-eq6.conf&quot;&gt;here&lt;/a&gt; which shows the structure of &lt;code&gt;args&lt;/code&gt; it expects.&lt;/p&gt;
&lt;p&gt;When a pre-amp gain is required, which is usually the case when applying EQ, the first EQ band needs to be modified to apply a &lt;code&gt;bq_highshelf&lt;/code&gt; filter at frequency &lt;code&gt;0 Hz&lt;/code&gt;with the provided negative gain. Pre-amp gain is always negative to offset the effect of possible clipping introduced by the amplification resulting from EQ. For the example preceding,&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  type    = builtin,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  name    = eq_band_1,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  label   = bq_highshelf,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  control = { Freq = 0, Gain = -6.0, Q = 1.0 },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarly, for &lt;code&gt;Filter 1&lt;/code&gt; this would be&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  type    = builtin,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  name    = eq_band_2,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  label   = bq_lowshelf,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  control = { Freq = 105, Gain = -5.2, Q = 0.7 },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similarly, for the other filters.&lt;/p&gt;
&lt;p&gt;PipeWire as of this writing, doesn&#39;t have helpers to create module arguments in code. &lt;code&gt;fprintf&lt;/code&gt; is used for constructing filter module arguments as a string.&lt;/p&gt;
&lt;p&gt;First open a &lt;code&gt;memstream&lt;/code&gt; ,&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;char&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; *&lt;/span&gt;&lt;span&gt;args &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; NULL&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;size_t&lt;/span&gt;&lt;span&gt; size;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;FILE &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;*&lt;/span&gt;&lt;span&gt;memstream &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; open_memstream&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;args&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;size&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Write a helper function which generates a &lt;code&gt;node&lt;/code&gt; entry for the &lt;code&gt;nodes&lt;/code&gt; array in the filter chain configuration.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;struct&lt;/span&gt;&lt;span&gt; eq_node_param {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;	char&lt;/span&gt;&lt;span&gt; filter_type[&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;4&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;	char&lt;/span&gt;&lt;span&gt; filter[&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;4&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;	uint32_t&lt;/span&gt;&lt;span&gt; freq;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;	float&lt;/span&gt;&lt;span&gt; gain;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;	float&lt;/span&gt;&lt;span&gt; q_fact;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;void&lt;/span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; init_eq_node&lt;/span&gt;&lt;span&gt;(FILE &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;f&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; const&lt;/span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; char&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;node_desc&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;{&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;node.description = &lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\&amp;quot;%s\&amp;quot;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;, node_desc);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;media.name = &lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\&amp;quot;%s\&amp;quot;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;, node_desc);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;filter.graph = {&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;nodes = [&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;void&lt;/span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; add_eq_node&lt;/span&gt;&lt;span&gt;(FILE &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;f&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; struct&lt;/span&gt;&lt;span&gt; eq_node_param &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;param&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; uint32_t&lt;/span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; eq_band_idx&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;{&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;type = builtin&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;name = eq_band_&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;%d\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;, eq_band_idx);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;	if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;strcmp&lt;/span&gt;&lt;span&gt;(param-&amp;gt;filter_type,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;PK&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;		fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;label = bq_peaking&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; else if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;strcmp&lt;/span&gt;&lt;span&gt;(param-&amp;gt;filter_type,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;LSC&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;		fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;label = bq_lowshelf&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; else if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;strcmp&lt;/span&gt;&lt;span&gt;(param-&amp;gt;filter_type,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;HSC&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;		fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;label = bq_highshelf&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;		fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;label = bq_peaking&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;control = { &lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;Freq&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = &lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;%d \&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;Q&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = &lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;%f \&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;Gain&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = &lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;%f&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;, param-&amp;gt;freq, param-&amp;gt;q_fact, param-&amp;gt;gain);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;}&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;void&lt;/span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; end_eq_node&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;struct&lt;/span&gt;&lt;span&gt; impl &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;impl&lt;/span&gt;&lt;span&gt;, FILE &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;f&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; uint32_t&lt;/span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; number_of_nodes&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;]&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;links = [&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;	for&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;uint32_t&lt;/span&gt;&lt;span&gt; i &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 1&lt;/span&gt;&lt;span&gt;; i &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span&gt; number_of_nodes; i&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;++&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;		fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;{ output = &lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;eq_band_&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;%d&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;:Out&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; input = &lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;eq_band_&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;%d&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;:In&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; }&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;, i, i &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;+&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 1&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;]&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;}&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;audio.channels = &lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;%d\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;, impl-&amp;gt;channels);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;audio.position = &lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;%s\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;, impl-&amp;gt;position);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;capture.props = {&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;node.name = &lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;effect_input.eq&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;%d\&amp;quot;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;, number_of_nodes);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;media.class = Audio/Sink&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;}&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;playback.props = {&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;node.name = &lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\&amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;effect_output.eq&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;%d\&amp;quot;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;, number_of_nodes);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;node.passive = true&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;}&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fprintf&lt;/span&gt;&lt;span&gt;(f,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;}&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\n&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The parsing function relies on the preceding helpers and is now straight forward. Read line by line from the file stream using &lt;code&gt;getline&lt;/code&gt; and use &lt;code&gt;sscanf&lt;/code&gt; to parse the line itself and call these helpers.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	spa_zero&lt;/span&gt;&lt;span&gt;(eq_param);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;	/* Check for Pre-amp gain */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	nread &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; getline&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;line&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;len&lt;/span&gt;&lt;span&gt;, f);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;	if&lt;/span&gt;&lt;span&gt; (nread &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;!= -&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;amp;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; sscanf&lt;/span&gt;&lt;span&gt;(line,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;%*s %6f %*s&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;eq_param.gain)&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 1&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;		memcpy&lt;/span&gt;&lt;span&gt;(eq_param.filter,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;ON&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 2&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;		memcpy&lt;/span&gt;&lt;span&gt;(eq_param.filter_type,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;HSC&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 3&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		eq_param.freq&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		eq_param.q_fact&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 1.0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;		add_eq_node&lt;/span&gt;&lt;span&gt;(memstream,&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;eq_param, eq_band_idx);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		eq_band_idx&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;++&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		eq_bands&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;++&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;	/* Read the filter bands */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;	while&lt;/span&gt;&lt;span&gt; ((nread &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; getline&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;line&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;len&lt;/span&gt;&lt;span&gt;, f))&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; != -&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;1&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;		spa_zero&lt;/span&gt;&lt;span&gt;(eq_param);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;		if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;sscanf&lt;/span&gt;&lt;span&gt;(line,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;%*s %*d&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;: &lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;%3s %3s %*s %5d %*s %*s %6f %*s %*c %6f&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span&gt;, eq_param.filter, eq_param.filter_type,&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;eq_param.freq,&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;eq_param.gain,&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;eq_param.q_fact)&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 5&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;			if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;strcmp&lt;/span&gt;&lt;span&gt;(eq_param.filter,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;ON&amp;quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; ==&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;/span&gt;&lt;span&gt;) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;				add_eq_node&lt;/span&gt;&lt;span&gt;(memstream,&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;eq_param, eq_band_idx);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;				eq_band_idx&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;++&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;				eq_bands&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;++&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;			}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;		}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	end_eq_node&lt;/span&gt;&lt;span&gt;(impl, memstream, eq_bands);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	fclose&lt;/span&gt;&lt;span&gt;(memstream);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	memstream &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; NULL&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, &lt;code&gt;args&lt;/code&gt; has a string representation of the parametric equalizer configuration which can now be passed while loading the filter chain module.&lt;/p&gt;
&lt;h1 id=&quot;loading-filter-chain&quot;&gt;Loading &lt;em&gt;&lt;strong&gt;&lt;code&gt;filter-chain&lt;/code&gt;&lt;/strong&gt;&lt;/em&gt;&lt;/h1&gt;
&lt;p&gt;The filter chain module can now be loaded with &lt;code&gt;args&lt;/code&gt; from the previous step.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;	struct&lt;/span&gt;&lt;span&gt; pw_impl_module &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;*&lt;/span&gt;&lt;span&gt;eq_module;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	eq_module &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; pw_context_load_module&lt;/span&gt;&lt;span&gt;(impl&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;-&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;context&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;				&amp;quot;libpipewire-module-filter-chain&amp;quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;				args,&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; NULL&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h1 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;The merge request for this upstream can be found &lt;a rel=&quot;external&quot; href=&quot;https://gitlab.freedesktop.org/pipewire/pipewire/-/merge_requests/2006&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The module allows one to leverage the built-in equalizer capabilities of PipeWire via it’s filter chain module without having to resort to writing the configuration by hand.&lt;/p&gt;
&lt;p&gt;There are examples on writing &lt;a rel=&quot;external&quot; href=&quot;https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/master/src/modules/module-example-filter.c&quot;&gt;filter&lt;/a&gt;, &lt;a rel=&quot;external&quot; href=&quot;https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/master/src/modules/module-example-sink.c&quot;&gt;sink&lt;/a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https://gitlab.freedesktop.org/pipewire/pipewire/-/blob/master/src/modules/module-example-source.c&quot;&gt;source&lt;/a&gt; modules in the PipeWire repository.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Supporting ALSA compressed offload in PipeWire</title>
        <published>2024-03-18T00:00:00+00:00</published>
        <updated>2024-03-18T00:00:00+00:00</updated>
        
        <author>
          <name>Sanchayan Maity</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://sanchayanmaity.net/posts/pipewire-compressed-offload/"/>
        <id>https://sanchayanmaity.net/posts/pipewire-compressed-offload/</id>
        
        <content type="html" xml:base="https://sanchayanmaity.net/posts/pipewire-compressed-offload/">&lt;h2 id=&quot;background&quot;&gt;Background&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Editor&#39;s note&lt;/strong&gt;: this work was completed in late 2022 but this post was unfortunately delayed.&lt;/p&gt;
&lt;p&gt;Modern day audio hardware these days comes integrated with Digital Signal
Processors integrated in SoCs and audio codecs. Processing compressed or encoded
data in such DSPs results in power savings in comparison to carrying out such
processing on the CPU.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     +---------+      +---------+       +---------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     |   CPU   | ---&amp;gt; |   DSP   | ---&amp;gt;  |  Codec  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     |         | &amp;lt;--- |         | &amp;lt;---  |         |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;     +---------+      +---------+       +---------+&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This post takes a look at how all this works.&lt;/p&gt;
&lt;h2 id=&quot;audio-processing&quot;&gt;Audio processing&lt;/h2&gt;
&lt;p&gt;A traditional audio pipeline, might look like below. An application reads encoded
audio and then might leverage a media framework like GStreamer or library like
ffmpeg to decode the encoded audio to PCM. The decoded audio stream is then handed
off to an audio server like PulseAudio or PipeWire which eventually hands it off
to ALSA.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    +----------------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    |   Application  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    +----------------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                            |           mp3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    +----------------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    |    GStreamer   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    +----------------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                            |          pcm&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    +----------------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    |    PipeWire    |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    +----------------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                            |          pcm&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    +----------------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    |      ALSA      |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    +----------------+&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With ALSA Compressed offload, the same audio pipeline would look like this. The
encoded audio stream would be passed through to ALSA. ALSA would then, via it&#39;s
compressed offload API, send the encoded data to the DSP. DSP does the decode
and render.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    +----------------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    |   Application  |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    +----------------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                            |           mp3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    +----------------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    |    GStreamer   |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    +----------------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                            |          mp3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    +----------------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    |    PipeWire    |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    +----------------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                            |          mp3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    +----------------+&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    |      ALSA      |&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;                    +----------------+&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Since the processing of the compressed data is handed to a specialised hardware
namely the DSP, this results in a dramatic reduction of power consumption compared
to CPU based processing.&lt;/p&gt;
&lt;h2 id=&quot;challenges&quot;&gt;Challenges&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;ALSA Compressed Offload API which is a different API compared to the ALSA PCM
interface, provides the control and data streaming interface for audio DSPs.
This API is provided by the &lt;a rel=&quot;external&quot; href=&quot;https://github.com/alsa-project/tinycompress&quot;&gt;tinycompress&lt;/a&gt;
library.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;With PCM there is the notion of &lt;code&gt;bytes ~ time&lt;/code&gt;. For example, 1920 bytes,
S16LE, 2 channels, 48 KHz would correspond to 10 ms. This breaks down
for compressed streams. It&#39;s impossible to estimate reliably the duration of
audio buffers when handling most compressed data.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;While sampling rate, number of channels and bits per sample are enough to
completely specify PCM, various parameters may have to be specified to enable
the DSP to deal with multiple compressed formats.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;For some codecs, additional firmware has to be loaded by the DSP. This has to
be handled outside the context of audio server.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;requirements&quot;&gt;Requirements&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Expose all possible compressed formats.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Allow a client to negotiate the format.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Stream encoded audio frames and not PCM.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;pipewire&quot;&gt;PipeWire&lt;/h2&gt;
&lt;p&gt;PipeWire has become the default sound server on Linux, handling multimedia
routing and audio pipeline processing. It offers capture and playback for
both audio and video with minimal latency and support for PulseAudio, JACK,
ALSA, and GStreamer-based applications.&lt;/p&gt;
&lt;h2 id=&quot;spa&quot;&gt;SPA&lt;/h2&gt;
&lt;p&gt;PipeWire is built on top of SPA (Simple Plugin API), a header only API for
building plugins. SPA provides a set of low-level primitives.&lt;/p&gt;
&lt;p&gt;SPA plugins are shared libraries (.so files) that can be loaded at runtime.
Each library provides one or more &lt;code&gt;factories&lt;/code&gt;, each of which may implement
several &lt;code&gt;interfaces&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The most interesting interface is the &lt;code&gt;node&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A node consumes or produces buffers through ports.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;In addition to ports and other well defined interface methods, a node can have
events and callbacks.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ports are also first class objects within the node.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;There are a set of port related interface methods on the node.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There may be statically allocated ports in instance initialization.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There can be dynamic ports managed with &lt;code&gt;add_port&lt;/code&gt; and &lt;code&gt;remove_port&lt;/code&gt; methods.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ports have &lt;code&gt;params&lt;/code&gt; which can be queried using the &lt;code&gt;port_enum_params&lt;/code&gt; method
to determine the list of formats &lt;code&gt;EnumFormat&lt;/code&gt;, the currently configured format
&lt;code&gt;Format&lt;/code&gt;, buffer configuration, latency information, &lt;code&gt;I/O areas&lt;/code&gt; for data structures
shared by port, and other such information.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Some params such as the selected format can be set using the &lt;code&gt;port_set_format&lt;/code&gt;
method.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;implementing-compressed-sink-spa-node&quot;&gt;Implementing compressed sink SPA node&lt;/h2&gt;
&lt;p&gt;This section covers some primary implementation details of a PipeWire SPA node which
can accept an encoded audio stream and then write it out using ALSA compressed
offload API.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;static const&lt;/span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; struct&lt;/span&gt;&lt;span&gt; spa_node_methods impl_node &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	SPA_VERSION_NODE_METHODS,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.add_listener &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; impl_node_add_listener,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.set_callbacks &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; impl_node_set_callbacks,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.enum_params &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; impl_node_enum_params,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.set_io &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; impl_node_set_io,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.send_command &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; impl_node_send_command,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.add_port &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; impl_node_add_port,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.remove_port &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; impl_node_remove_port,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.port_enum_params &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; impl_node_port_enum_params,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.port_set_param &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; impl_node_port_set_param,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.port_use_buffers &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; impl_node_port_use_buffers,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.port_set_io &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; impl_node_port_set_io,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.process &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; impl_node_process,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Some key node methods defining the actual implementation are as follows.&lt;/p&gt;
&lt;h3 id=&quot;port-enum-params&quot;&gt;&lt;strong&gt;&lt;code&gt;port_enum_params&lt;/code&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;params&lt;/code&gt; for ports are queried using this method. This is akin to finding out
the capabilities of a port on the node.&lt;/p&gt;
&lt;p&gt;For the compressed sink SPA node, the following are present.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;EnumFormat&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This builds up a list of the encoded formats that&#39;s handled by the node to
return as a result.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Format&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Returns the currently set format on the port.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;Buffers&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Provides information on size, minimum, and maximum number of buffers to be used
when streaming data to this node.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;IO&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The node exchanges information via &lt;code&gt;IO&lt;/code&gt; areas. There are various type of &lt;code&gt;IO&lt;/code&gt;
areas like buffers, clock, position. Compressed sink SPA node only advertises
&lt;code&gt;buffer&lt;/code&gt; areas at the moment.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The results are returned in an &lt;a rel=&quot;external&quot; href=&quot;https://docs.pipewire.org/page_spa_pod.html&quot;&gt;SPA POD&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;port-use-buffers&quot;&gt;&lt;strong&gt;&lt;code&gt;port_use_buffers&lt;/code&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Tells the port to use the given buffers via the &lt;code&gt;IO&lt;/code&gt; area.&lt;/p&gt;
&lt;h3 id=&quot;port-set-param&quot;&gt;&lt;strong&gt;&lt;code&gt;port_set_param&lt;/code&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;The various &lt;code&gt;params&lt;/code&gt; on the port are set via this method.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Format&lt;/code&gt; &lt;code&gt;param&lt;/code&gt; request sets the actual encoded format that&#39;s going to be streamed
to this SPA node by a pipewire client like &lt;code&gt;pw-cat&lt;/code&gt; or application for sending to
the DSP.&lt;/p&gt;
&lt;h3 id=&quot;process&quot;&gt;&lt;strong&gt;&lt;code&gt;process&lt;/code&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Buffers containing the encoded media are handled here. The media stream is
written to the IO buffer area which were provided in &lt;code&gt;use_buffers&lt;/code&gt;. The encoded
media stream is written to the DSP by calling &lt;code&gt;compress_write&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;add-port-and-remove-port&quot;&gt;&lt;strong&gt;&lt;code&gt;add_port&lt;/code&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;code&gt;remove_port&lt;/code&gt;&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Since dynamic ports aren&#39;t supported, these methods return a &lt;code&gt;ENOTSUP&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&quot;pw-cat&quot;&gt;&lt;code&gt;pw-cat&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;pw-cat&lt;/code&gt; was modified to support negotiation of encoded formats and passing the
encoded stream as is when linked to the compressed sink node.&lt;/p&gt;
&lt;h2 id=&quot;deploying-on-hardware&quot;&gt;Deploying on hardware&lt;/h2&gt;
&lt;p&gt;Based on discussions with upstream compress offload maintainers, we chose a
Dragonboard 845c with the Qualcomm SDM845 SoC as our test platform.&lt;/p&gt;
&lt;p&gt;For deploying Linux on Embedded devices, the tool of choice is Yocto.
Yocto is a build automation framework and cross-compile environment used to
create custom Linux distributions/board support packages for embedded devices.&lt;/p&gt;
&lt;p&gt;Primary dependencies are&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;tinycompress&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;ffmpeg&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;PipeWire&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;WirePlumber&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code&gt;tinycompress&lt;/code&gt; library is what provides the compressed offload API. It makes
&lt;code&gt;ioctl()&lt;/code&gt; calls to the underlying kernel driver/sound subsystem.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ffmpeg&lt;/code&gt; is a dependency for the example &lt;code&gt;fcplay&lt;/code&gt; utility provided by
&lt;code&gt;tinycompress&lt;/code&gt;. It&#39;s also used in &lt;code&gt;pw-cat&lt;/code&gt; to read basic metadata of the encoded
media. This is then used to determine and negotiate the format with the compressed
sink node.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;PipeWire&lt;/code&gt; is where the compressed sink node would reside and &lt;code&gt;WirePlumber&lt;/code&gt; acting
as the session manager for &lt;code&gt;PipeWire&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Going into how Yocto works is beyond the scope of what can be covered in a blog
post. Basic Yocto project concepts can be found &lt;a rel=&quot;external&quot; href=&quot;https://docs.yoctoproject.org/overview-manual/concepts.html?highlight=meta+layer#yocto-project-concepts&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In Yocto speak, a custom
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/asymptotic-io/meta-asymptotic&quot;&gt;meta layer&lt;/a&gt; was written.&lt;/p&gt;
&lt;p&gt;Yocto makes it quite easy to build &lt;code&gt;autoconf&lt;/code&gt; based projects. A new &lt;code&gt;tinycompress&lt;/code&gt;
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/asymptotic-io/meta-asymptotic/blob/master/recipes-multimedia/tinycompress/tinycompress.bb&quot;&gt;bitbake recipe&lt;/a&gt;
was written to build the latest sources from upstream and also include the
&lt;code&gt;fcplay&lt;/code&gt; and &lt;code&gt;cplay&lt;/code&gt; utilities for initial testing.&lt;/p&gt;
&lt;p&gt;The existing PipeWire and WirePlumber recipes were modified to point to custom git
sources with minor changes to default settings included as part of the build.&lt;/p&gt;
&lt;h2 id=&quot;updates-since-the-original-work&quot;&gt;Updates since the original work&lt;/h2&gt;
&lt;p&gt;Since we completed the original patches, a number of changes have happened thanks
to the community (primarily Carlos Giani). These include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;A device plugin for autodetecting compress nodes on the system&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Replacing &lt;code&gt;tinycompress&lt;/code&gt; with an internal library to make all the requisite
&lt;code&gt;ioctl()&lt;/code&gt;s&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Compressed format detection (which was previously waiting on
&lt;a rel=&quot;external&quot; href=&quot;https://github.com/alsa-project/tinycompress/pull/16&quot;&gt;an upstream API addition we implemented in &lt;code&gt;tinycompress&lt;/code&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;future-work&quot;&gt;Future work&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Make compressed sink node provide clocking information. While the
API provides a method to retrieve the timestamp information, the relevant
timestamp fields seem to be not populated by the &lt;code&gt;q6asm-dai&lt;/code&gt; driver.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Validate other encoded formats. So far only MP3 and FLAC have been validated.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;May be the wider community can help test this on other hardware.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add capability to GStreamer plugin to work with compressed sink node. This
would also help in validating pause and resume.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Automate debugging using GDB scripting</title>
        <published>2021-11-13T00:00:00+00:00</published>
        <updated>2021-11-13T00:00:00+00:00</updated>
        
        <author>
          <name>Sanchayan Maity</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://sanchayanmaity.net/posts/gdb-scripting/"/>
        <id>https://sanchayanmaity.net/posts/gdb-scripting/</id>
        
        <content type="html" xml:base="https://sanchayanmaity.net/posts/gdb-scripting/">&lt;p&gt;For a while, have had the pleasure of working on a GStreamer
&lt;a rel=&quot;external&quot; href=&quot;https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/572&quot;&gt;plugin&lt;/a&gt;
in Rust at work. The plugin basically rounds the corners of an incoming video,
something akin to the &lt;code&gt;border-radius&lt;/code&gt; property in CSS. Below is how it looks
like when running on a video.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/roundedcorners.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The GStreamer pipeline for the same.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;gst-launch-1.0&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; filesrc location=~/Downloads/bunny.mp4 ! decodebin ! videoconvert ! roundedcorners border-radius-px=&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ! videoconvert ! gtksink&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This was the first time working on a video plugin in GStreamer. Had a lot to
learn on how to use the &lt;code&gt;BaseTransform&lt;/code&gt; class from GStreamer, among other
things. Without getting into the GStreamer specific details here, basically ran
into a problem for which needed some debugging for figuring out what was going
on in the internals of GStreamer.&lt;/p&gt;
&lt;p&gt;Now, while using GDB from the command line has never been a problem, but, the
straight forward regular approach is time-consuming. Start the pipeline, then
attach gdb to a running process, place breakpoints by manually typing out the
whole thing and then start. For one off debugging sessions, where perhaps you
just want to inspect the backtrace from a crash or may be look into a
deadlock condition where your code hung, this could be fine. However, when you
have to repeat this multiple times do a source code change compile and then
select again it becomes frustrating.&lt;/p&gt;
&lt;h2 id=&quot;gdb-dashboard&quot;&gt;GDB Dashboard&lt;/h2&gt;
&lt;p&gt;Looking for a better way, &lt;a rel=&quot;external&quot; href=&quot;https://github.com/cyrus-and/gdb-dashboard&quot;&gt;gdb-dashboard&lt;/a&gt;
is what first came up as an option. This is quite useful since it can give the needed
information without having to type anything. Using gdb
&lt;a rel=&quot;external&quot; href=&quot;https://git.sr.ht/~sanchayanmaity/dotfiles/tree/master/item/gdb/.gdbinit.d/hooks&quot;&gt;hooks&lt;/a&gt;,
the dashboard can be triggered when appropriate. See the rest of the &lt;a rel=&quot;external&quot; href=&quot;https://git.sr.ht/~sanchayanmaity/dotfiles/tree/master/item/gdb/.gdbinit.d&quot;&gt;gdb
configuration&lt;/a&gt;
to get an idea. This is useful in scenarios like where code is stuck due to a
deadlock and one needs to look at the backtrace of a crash or any such one off
simple investigation.&lt;/p&gt;
&lt;h2 id=&quot;construct-breakpoint-command-in-neovim-copy-to-clipboard&quot;&gt;Construct breakpoint command in neovim &amp;amp; copy to clipboard&lt;/h2&gt;
&lt;p&gt;The next small improvement is more specific to neovim. Navigating source code
with neovim opened in one kitty tab and gdb running in terminal in next tab or
a split is a preferred workflow personally. Being able to place a breakpoint
without having to type anything out on the gdb prompt would be convenient. The
vimscript code below generates the gdb command, considering the current line
and file on which the cursor is at in the source when opened in neovim.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;plain&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;function! CopyBpLocToClipboard() abort&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  let linenumber = line(&amp;quot;.&amp;quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  let filepath = expand(&amp;quot;%&amp;quot;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  let breakpoint = &amp;quot;break &amp;quot; . filepath . &amp;quot;:&amp;quot; . linenumber&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;  silent execute &amp;quot;!wl-copy &amp;quot; . breakpoint&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;endfunction&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;nnoremap &amp;lt;silent&amp;gt; &amp;lt;Leader&amp;gt;yb :&amp;lt;C-U&amp;gt;call CopyBpLocToClipboard()&amp;lt;CR&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By using the preceding key binding, a command like below gets copied to the
clipboard which can be just pasted on gdb prompt.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;break&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; subprojects/gst-plugins-base/gst-libs/gst/video/video-frame.c:104&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nifty!!!&lt;/p&gt;
&lt;h2 id=&quot;gdb-scripting&quot;&gt;GDB scripting&lt;/h2&gt;
&lt;p&gt;Now imagine a scenario where perhaps one wants to look at multiple places in the
source code and when the program is running, inspect certain variables or just
print out a back trace each time a specific code point is reached.&lt;/p&gt;
&lt;p&gt;The manual way to do this is to load the executable in gdb or attach to a
running process, place a break point, run, inspect the local variables or print
stack trace, place the next break point and repeat this whole process. Just
time-consuming.&lt;/p&gt;
&lt;p&gt;GDB can completely automate the preceding process like below.&lt;/p&gt;
&lt;p&gt;Below is the &lt;code&gt;.gdbinit&lt;/code&gt; file applicable for the problem facing encountered at
work. This is what&#39;s called a command file by gdb.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; confirm off&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; breakpoint pending on&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; logging on&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; logging overwrite on&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; print pretty on&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; pagination off&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;break&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; subprojects/gst-plugins-base/gst-libs/gst/video/video-frame.c:104 if meta&lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;n_planes ==&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 4&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;break&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; subprojects/gst-plugins-base/gst-libs/gst/video/gstvideometa.c:228&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;break&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; subprojects/gstreamer/gst/gstbuffer.c:1410&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;break&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; subprojects/gst-plugins-base/gst-libs/gst/video/gstvideometa.c:231&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;break&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; subprojects/gst-plugins-base/gst-libs/gst/video/gstvideometa.c:237&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;break&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; subprojects/gst-plugins-base/gst-libs/gst/video/video-frame.c:136&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;commands&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;    print&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; i&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;    print&lt;/span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;frame&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    enable&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    enable&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    enable&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 4&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    enable&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    enable&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 6&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    continue&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;commands&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;    print&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; offset&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    continue&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;commands&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;    print&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; offset&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;    print&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; size&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    continue&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;commands&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 4&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;    print&lt;/span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;GstBufferImpl&lt;/span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; *&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;buffer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;    print&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; idx&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;    print&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; length&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;    print&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; skip&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    continue&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;commands&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    disable&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    disable&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    disable&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 4&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;    print&lt;/span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; *&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;GstBufferImpl&lt;/span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; *&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;buffer&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;    print&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; info&lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;data&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;    print&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; skip&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;    print&lt;/span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;data&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    continue&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;commands&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 6&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;    print&lt;/span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;frame&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    quit&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;end&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;disable&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;disable&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;disable&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 4&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;disable&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;disable&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 6&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;run&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Below is the command to debug the GStreamer plugin in this pipeline with gdb.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;gdb&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; --nx -x&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; .gdbinit&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; --args&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; env RUST_BACKTRACE=&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; GST_DEBUG=3,basetransform:6 GST_PLUGIN_PATH=&lt;/span&gt;&lt;span&gt;$GST_PLUGIN_PATH&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;:~/GitSources/gst-plugins-rs/target/debug gst-launch-1.0 filesrc location=~/Downloads/bunny.mp4 ! decodebin ! videoconvert ! video/x-raw,format=I420 ! roundedcorners border-radius-px=&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ! video/x-raw,format=A420 ! videoconvert ! gtksink&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the preceding command, the &lt;code&gt;-x&lt;/code&gt; parameter tells gdb to use the command file.
The &lt;code&gt;--nx&lt;/code&gt; flag tells gdb to not read any &lt;code&gt;.gdbinit&lt;/code&gt; files in any directory, as
&lt;code&gt;gdb-dashboard&lt;/code&gt; isn&#39;t intended to be used for this. &lt;code&gt;--args&lt;/code&gt; is how one tells
gdb what to run, which is the GStreamer pipeline in this case. See &lt;code&gt;gdb --help&lt;/code&gt;
for details on the flags.&lt;/p&gt;
&lt;p&gt;Now, consider what the command file does. The ones below are just some
settings for gdb to use. Note that logging and pretty printing are enabled.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; confirm off&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; breakpoint pending on&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; logging on&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; logging overwrite on&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; print pretty on&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;set&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; pagination off&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, specify the breakpoints. There are six breakpoints. These are the source
code locations of interest.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;break&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; subprojects/gst-plugins-base/gst-libs/gst/video/video-frame.c:104 if meta&lt;/span&gt;&lt;span&gt;-&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;n_planes ==&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 4&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;break&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; subprojects/gst-plugins-base/gst-libs/gst/video/gstvideometa.c:228&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;break&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; subprojects/gstreamer/gst/gstbuffer.c:1410&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;break&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; subprojects/gst-plugins-base/gst-libs/gst/video/gstvideometa.c:231&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;break&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; subprojects/gst-plugins-base/gst-libs/gst/video/gstvideometa.c:237&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;break&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; subprojects/gst-plugins-base/gst-libs/gst/video/video-frame.c:136&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Breakpoints can be enabled conditionally. The &lt;code&gt;if meta-&amp;gt;n_planes == 4&lt;/code&gt; implies
to consider this breakpoint only when a video frame with 4 planes is received.&lt;/p&gt;
&lt;p&gt;Next gdb has to be told what should be done when each of the preceding
breakpoints is hit.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;commands&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 1&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;    print&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; i&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;&quot;&gt;    print&lt;/span&gt;&lt;span style=&quot;color: #FD971F;&quot;&gt; *&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;frame&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    enable&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    enable&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    enable&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 4&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    enable&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    enable&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 6&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;    continue&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;commands 1&lt;/code&gt; implies these are the commands for gdb to execute when breakpoint
1 is hit. When breakpoint 1 is hit, the value of &lt;code&gt;i&lt;/code&gt; and &lt;code&gt;frame&lt;/code&gt; gets printed.
The other breakpoints get enabled only after the first one is hit. This is
because at the end of command file, the following commands&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;disable&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 2&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;disable&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 3&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;disable&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 4&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;disable&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 5&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;disable&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 6&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;instruct gdb to start with these breakpoints off. These get enabled only
when breakpoint 1 is hit. The &lt;code&gt;continue&lt;/code&gt; just tells gdb to continue, as gdb
shouldn&#39;t stop on hitting a breakpoint and logs can be inspected in the
end using gdb log.&lt;/p&gt;
&lt;p&gt;Other breakpoints are specified similarly.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;run&lt;/code&gt; at the end tells gdb to start executing immediately. In normal usage
one would have to explicitly type &lt;code&gt;run&lt;/code&gt; on the gdb prompt to make gdb start
debugging.&lt;/p&gt;
&lt;p&gt;If it&#39;s not clear so far, basically whatever gdb commands would have been used
for debugging at the gdb prompt, is what gets specified in the command file as
well.&lt;/p&gt;
&lt;p&gt;After running the below on the terminal&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;gdb&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; --nx -x&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; .gdbinit&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; --args&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; env RUST_BACKTRACE=&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; GST_DEBUG=3,basetransform:6 GST_PLUGIN_PATH=&lt;/span&gt;&lt;span&gt;$GST_PLUGIN_PATH&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;:~/GitSources/gst-plugins-rs/target/debug gst-launch-1.0 filesrc location=~/Downloads/bunny.mp4 ! decodebin ! videoconvert ! video/x-raw,format=I420 ! roundedcorners border-radius-px=&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;100&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ! video/x-raw,format=A420 ! videoconvert ! gtksink&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The pipeline gets executed by gdb, considering the command file it was passed
and log whatever it was asked to log when each breakpoint is encountered. Since
logging and pretty printing were enabled earlier, gdb logs everything in
default &lt;code&gt;gdb.txt&lt;/code&gt; file. The exact log text file can be seen
&lt;a rel=&quot;external&quot; href=&quot;https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/572#note_1107146&quot;&gt;here&lt;/a&gt;,
with &lt;code&gt;gdbinit&lt;/code&gt; and the other two log files attached.&lt;/p&gt;
&lt;p&gt;Now, one can comfortably look at this log and see what&#39;s going on. Once the
command file is written, the whole debugging process is completely automated.
Run, sit back and then look at the logs.&lt;/p&gt;
&lt;p&gt;Using gdb is now a breeze and hassle-free experience. Being able to automate
and log the debugging process like this, also means you could share your
command file and someone else can replicate this.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A tale of working with Xilinx DisplayPort &amp; UIO</title>
        <published>2019-08-30T00:00:00+00:00</published>
        <updated>2019-08-30T00:00:00+00:00</updated>
        
        <author>
          <name>Sanchayan Maity</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://sanchayanmaity.net/posts/tale-of-working-with-uio/"/>
        <id>https://sanchayanmaity.net/posts/tale-of-working-with-uio/</id>
        
        <content type="html" xml:base="https://sanchayanmaity.net/posts/tale-of-working-with-uio/">&lt;p&gt;At work, a DisplayPort IP from Xilinx was being used. Xilinx doesn&#39;t provide any driver for this. There is a &lt;a rel=&quot;external&quot; href=&quot;https://www.xilinx.com/support/documentation/ip_documentation/v_dp_txss1/v2_0/pg299-v-dp-txss1.pdf&quot;&gt;TX&lt;/a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https://www.xilinx.com/support/documentation/ip_documentation/v_dp_rxss1/v2_0/pg300-v-dp-rxss1.pdf&quot;&gt;RX&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Bare metal code support is provided, however, support was needed for Linux. Ignoring interrupts, it&#39;s easy to get this bare metal code to work on Linux. Xilinx&#39;s bare metal code at it&#39;s core uses &lt;a rel=&quot;external&quot; href=&quot;https://github.com/Xilinx/embeddedsw/blob/master/lib/bsp/standalone/src/common/xil_io.h#L219&quot;&gt;Xil_Out32&lt;/a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https://github.com/Xilinx/embeddedsw/blob/master/lib/bsp/standalone/src/common/xil_io.h#L147&quot;&gt;Xil_In32&lt;/a&gt;
function for writing and reading to registers. The implementations for these can be replaced with mmap for accessing the registers. For DP TX side, doesn&#39;t need to handle interrupts and setting up the registers is enough. For RX, however, interrupts are needed to setup RX. For example, the link training for DP is initiated once a Training Pattern 1 (TP1) interrupt is detected.&lt;/p&gt;
&lt;p&gt;Linux being a monolithic kernel, there is clear separation between kernel and user space. Interrupts can only be handled in kernel space. However, it was easier to use the ported bare metal code in user space and so the need to handle interrupts in user space. One writes a driver to do all this but since only the interrupt part had to be handled in kernel space, the UIO subsystem was needed.&lt;/p&gt;
&lt;p&gt;Using the UIO subsystem, it&#39;s possible to handle the interrupts in kernel space while the rest like reading or writing to the registers can be done in user space. There&#39;s a &lt;a rel=&quot;external&quot; href=&quot;https://elixir.bootlin.com/linux/latest/source/drivers/uio/uio_pdrv_genirq.c&quot;&gt;Userspace I/O Platform driver with generic IRQ handling code&lt;/a&gt;. Taking the example of Xilinx DisplayPort RX here. Colleague who works on FPGA side generates the FPGA firmware along with device trees which has entries as per the peripherals configured on FPGA side, for example, DP RX peripheral can be in the memory region 0x80004000 to 0x80006000. An interrupt is assigned based on how the FPGA Programmable Logic (PL) connects to the Processing System (PS). PL is the FPGA and PS is the ARM64 SoC.&lt;/p&gt;
&lt;p&gt;The extended device tree entry looks like this. &lt;em&gt;reg&lt;/em&gt; specifies the memory that can be mmaped in user space and accessed while the &lt;em&gt;interrupts&lt;/em&gt; get used by the kernel code.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;SUBBLOCK_DP_BASE_v_dp_rxss1_0 {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    compatible &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;dprxss-uio&amp;quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    interrupt&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;-&lt;/span&gt;&lt;span&gt;parent &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;= &amp;lt;&amp;amp;&lt;/span&gt;&lt;span&gt;gic&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    interrupts &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;= &amp;lt;&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0 92 4 0 92 4&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    reg &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;= &amp;lt;0x&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; 0x&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;80004000&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; 0x&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; 0x&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;2000&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    status &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;okay&amp;quot;&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To link the UIO platform driver to this, add the following to the &lt;em&gt;bootargs&lt;/em&gt; environment variable in u-boot.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;uio_pdrv_genirq.of_id&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt;dprxss&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;-&lt;/span&gt;&lt;span&gt;uio&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is a need to do this, since the compatible property for device tree isn&#39;t specified in the driver. See &lt;a rel=&quot;external&quot; href=&quot;https://elixir.bootlin.com/linux/latest/source/drivers/uio/uio_pdrv_genirq.c#L252&quot;&gt;here&lt;/a&gt;. So it&#39;s a module parameter.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;static&lt;/span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; struct&lt;/span&gt;&lt;span&gt; of_device_id uio_of_genirq_match&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;[] =&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	{&lt;/span&gt;&lt;span style=&quot;color: #88846F;&quot;&gt; /* This is filled with module_parm */&lt;/span&gt;&lt;span&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	{&lt;/span&gt;&lt;span style=&quot;color: #88846F;&quot;&gt; /* Sentinel */&lt;/span&gt;&lt;span&gt; },&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;MODULE_DEVICE_TABLE&lt;/span&gt;&lt;span&gt;(of, uio_of_genirq_match);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;module_param_string&lt;/span&gt;&lt;span&gt;(of_id, uio_of_genirq_match[&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;0&lt;/span&gt;&lt;span&gt;].compatible,&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 128&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;MODULE_PARM_DESC&lt;/span&gt;&lt;span&gt;(of_id,&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; &amp;quot;Openfirmware id of the device to be handled by uio&amp;quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, a combination of poll and read can be used to wait for interrupts in user space. So all well and good, however, there are some caveats to know. Once an interrupt is handled in kernel code, it disables the interrupt.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;static&lt;/span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; irqreturn_t&lt;/span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; uio_pdrv_genirq_handler&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;int&lt;/span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt; irq&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; struct&lt;/span&gt;&lt;span&gt; uio_info &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;dev_info&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;	struct&lt;/span&gt;&lt;span&gt; uio_pdrv_genirq_platdata &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;*&lt;/span&gt;&lt;span&gt;priv &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; dev_info-&amp;gt;priv;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;	/* Just disable the interrupt in the interrupt controller, and&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;	 * remember the state so we can allow user space to enable it later.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;	 */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	spin_lock&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;priv-&amp;gt;lock);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;	if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;__test_and_set_bit&lt;/span&gt;&lt;span&gt;(UIO_IRQ_DISABLED,&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;priv-&amp;gt;flags))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;		disable_irq_nosync&lt;/span&gt;&lt;span&gt;(irq);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	spin_unlock&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;priv-&amp;gt;lock);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;	return&lt;/span&gt;&lt;span&gt; IRQ_HANDLED;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The interrupt re-enable logic is in the below function.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;static&lt;/span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; int&lt;/span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt; uio_pdrv_genirq_irqcontrol&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;struct&lt;/span&gt;&lt;span&gt; uio_info &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;dev_info&lt;/span&gt;&lt;span&gt;, s32 &lt;/span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;irq_on&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;	struct&lt;/span&gt;&lt;span&gt; uio_pdrv_genirq_platdata &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;*&lt;/span&gt;&lt;span&gt;priv &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; dev_info-&amp;gt;priv;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt;	unsigned long&lt;/span&gt;&lt;span&gt; flags;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;	/* Allow user space to enable and disable the interrupt&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;	 * in the interrupt controller, but keep track of the&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;	 * state to prevent per-irq depth damage.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;	 *&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;	 * Serialize this operation to support multiple tasks and concurrency&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;	 * with irq handler on SMP systems.&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #88846F;&quot;&gt;	 */&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	spin_lock_irqsave&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;priv-&amp;gt;lock, flags);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;	if&lt;/span&gt;&lt;span&gt; (irq_on) {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;		if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;__test_and_clear_bit&lt;/span&gt;&lt;span&gt;(UIO_IRQ_DISABLED,&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;priv-&amp;gt;flags))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;			enable_irq&lt;/span&gt;&lt;span&gt;(dev_info-&amp;gt;irq);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;		if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;!&lt;/span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;__test_and_set_bit&lt;/span&gt;&lt;span&gt;(UIO_IRQ_DISABLED,&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt; &amp;amp;&lt;/span&gt;&lt;span&gt;priv-&amp;gt;flags))&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;			disable_irq_nosync&lt;/span&gt;&lt;span&gt;(dev_info-&amp;gt;irq);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;	spin_unlock_irqrestore&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span&gt;priv-&amp;gt;lock, flags);&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;	return&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is called from &lt;a rel=&quot;external&quot; href=&quot;https://elixir.bootlin.com/linux/latest/source/drivers/uio/uio.c#L648&quot;&gt;uio_write&lt;/a&gt;. And if you know how &lt;a rel=&quot;external&quot; href=&quot;https://linux-kernel-labs.github.io/master/labs/device_drivers.html&quot;&gt;file operations&lt;/a&gt; work, this &lt;code&gt;uio_write&lt;/code&gt; is called when a &lt;em&gt;write&lt;/em&gt; system call is issued with a file descriptor received from opening the &lt;em&gt;/dev/uioX&lt;/em&gt; node.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;static const&lt;/span&gt;&lt;span style=&quot;color: #66D9EF;font-style: italic;&quot;&gt; struct&lt;/span&gt;&lt;span&gt; file_operations uio_fops &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.owner		&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; THIS_MODULE,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.open		&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; uio_open,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.release	&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; uio_release,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.read		&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; uio_read,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.write		&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; uio_write,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.mmap		&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; uio_mmap,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.poll		&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; uio_poll,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.fasync		&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; uio_fasync,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;	.llseek		&lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;=&lt;/span&gt;&lt;span&gt; noop_llseek,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;};&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, here comes the problem. After the first interrupt, no more interrupts were being handled. So, basically the write call wasn&#39;t working to re-enable the interrupt. Putting print statements in &lt;code&gt;uio_write&lt;/code&gt;, it could be seen that a call to the write function didn&#39;t result in invocation of &lt;code&gt;uio_write&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;After being perplexed and wasting 4-5 hours trying to figure out what&#39;s wrong, wrote a small piece of code outside the project workspace which opened &lt;code&gt;/dev/uioX&lt;/code&gt; and then did a write. In this case, the prints from &lt;code&gt;uio_write&lt;/code&gt; function which eventually called &lt;code&gt;uio_pdrv_genirq_irqcontrol&lt;/code&gt; to enable the interrupt could be seen. So, something was wrong with the project setup.&lt;/p&gt;
&lt;p&gt;Using neovim and ctags for code navigation, trying jump to definition on the write call, ended up in a &lt;code&gt;write.c&lt;/code&gt; file. The first initial project setup was done by the FPGA engineer colleague since Xilinx SDK generates bare metal code samples based on the design done. Had not noticed this file before. It seemed to be an artifact of the code ported over from bare metal and had a write function as below.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;c&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;__attribute__&lt;/span&gt;&lt;span&gt;((weak)) sint32 &lt;/span&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;write&lt;/span&gt;&lt;span&gt;(sint32 &lt;/span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;fd&lt;/span&gt;&lt;span&gt;, char8 &lt;/span&gt;&lt;span style=&quot;color: #F92672;&quot;&gt;*&lt;/span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;buf&lt;/span&gt;&lt;span&gt;, sint32 &lt;/span&gt;&lt;span style=&quot;color: #FD971F;font-style: italic;&quot;&gt;nbytes&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Being aware of the weak attribute from working in u-boot where it&#39;s used to define board specific functions over riding default ones. The GCC manual defines it as &lt;em&gt;The weak attribute causes the declaration to be emitted as a weak symbol rather than a global. This is primarily useful in defining library functions which can be overridden in user code&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;There was no other write function defined in the project. Ideally it should have been picked up from &lt;code&gt;glibc&lt;/code&gt;. However, this wasn&#39;t happening. Didn&#39;t need that write implementation in &lt;code&gt;write.c&lt;/code&gt; which was actually writing to a UART port, so after removal everything started working fine. DP link training was succeeding finally.&lt;/p&gt;
&lt;p&gt;One can read more about UIO &lt;a rel=&quot;external&quot; href=&quot;https://www.kernel.org/doc/html/latest/driver-api/uio-howto.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Building a Board Support Package using Yocto</title>
        <published>2019-01-16T00:00:00+00:00</published>
        <updated>2019-01-16T00:00:00+00:00</updated>
        
        <author>
          <name>Sanchayan Maity</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://sanchayanmaity.net/posts/building-a-bsp/"/>
        <id>https://sanchayanmaity.net/posts/building-a-bsp/</id>
        
        <content type="html" xml:base="https://sanchayanmaity.net/posts/building-a-bsp/">&lt;p&gt;This post assumes a basic working knowledge of Yocto/OpenEmbedded.&lt;/p&gt;
&lt;p&gt;At the current workplace, for the project, am responsible for everything be it app, kernel configuration, custom drivers or existing driver enhancements or setting up the complete board support package for the system. While having worked on OpenEmbedded/Yocto at the previous company, had no experience setting up a complete BSP. This meant having a custom meta layer for this project along with the required layers for Yocto to work and also the vendor specific layer which in this case was Xilinx, but, could be any for that matter. Accordingly, one would include &lt;code&gt;meta-samsung&lt;/code&gt;, &lt;code&gt;meta-ti&lt;/code&gt; or &lt;code&gt;meta-intel&lt;/code&gt; etc.&lt;/p&gt;
&lt;p&gt;One of the first decisions to make was regarding the flashing process. There was an eMMC on-board and also a SD card. It&#39;s possible to have one&#39;s own script and then use u-boot&#39;s &lt;code&gt;mmc write&lt;/code&gt; functions to format and write to the MMC. However, decided to go for the easier &lt;a rel=&quot;external&quot; href=&quot;https://github.com/pengutronix/genimage&quot;&gt;genimage&lt;/a&gt; approach. Yocto build system builds the relevant components and can pack it in a single image using a configuration like below.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;image&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; boot.vfat {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    vfat&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;        files&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;            &amp;quot;BOOT.bin&amp;quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;            &amp;quot;emergency.ub&amp;quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;            &amp;quot;image.ub&amp;quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;            &amp;quot;system.dtb&amp;quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;            &amp;quot;Image&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    size&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = 128M&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;image&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ged.img {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    hdimage&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    partition&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; boot {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;        partition-type&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0xC&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;        bootable&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = &amp;quot;true&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;        image&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = &amp;quot;boot.vfat&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    partition&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; rootfs {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;        partition-type&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0x83&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;        image&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = &amp;quot;rootfs-zynqmp.ext4&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;        size&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; =&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; 0&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This gives a single file with an &lt;code&gt;img&lt;/code&gt; extension which can be used to flash the SD card or eMMC using the &lt;strong&gt;dd&lt;/strong&gt; command.&lt;/p&gt;
&lt;p&gt;Now, to use Yocto requires the use of several meta layers to be put together. One way is to use the repo tool which is also used in the Android world. However, there was a need for something more along with Docker integration. Wondering if someone has already done this kind of work, went searching on Google and came across &lt;a rel=&quot;external&quot; href=&quot;https://github.com/YoeDistro/yoe-distro&quot;&gt;yoe-distro&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;yoe-distro&lt;/code&gt; provided a perfect template on which to base the work on. Only need integrate the layers required and it does the rest. Docker integration is also included. Now, in case you are wondering why Docker is required, Yocto/ OpenEmbedded builds can be sensitive to host distribution setup. Also in this case, Xilinx&#39;s support provided through Yocto would not build on Ubuntu 18.04. Downgrading would result in waste of time and isn&#39;t actually a solution. Even if worked on Ubuntu 18.04, future upgrades may result in the build not working.&lt;/p&gt;
&lt;p&gt;Docker solves this problem by providing a sandboxed environment, think of &lt;code&gt;chroot&lt;/code&gt; or BSD jails simplified and on steroids. So ended up integrating the vendor specific meta layers and added custom layer to provide customisations. Getting started with Yocto definitely requires putting in some effort, but, adding customisations and stuff is lot easy or at least has been easy for what was being done.&lt;/p&gt;
&lt;p&gt;For example, there is a need to build the kernel from source, since there are some custom patches and if nothing else custom device trees which enable support for custom Xilinx IP core drivers are needed. One problem was internally the use of Atlassian Stash and trying to even just clone the source tree from Stash requires authentication. Wasn&#39;t sure how to do this in Yocto while without exposing SSH keys or account information. &lt;code&gt;yoe-distro&lt;/code&gt; setup helped here.&lt;/p&gt;
&lt;p&gt;The linux source is added as a git submodule just like the meta layers and then a custom recipe builds that.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;SRC_URI&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = &amp;quot;git://${&lt;/span&gt;&lt;span&gt;TOPDIR&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;}/sources/ged4k-linux-kernel;protocol=file;branch=ged4k_v2018.2&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;SRCREV&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = &amp;quot;fbec50e15d7b04f44690eb115d2cddd4423e0326&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;SRC_URI_append&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; += &amp;quot; file://defconfig &lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;                    file://fragment.cfg &lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;                    &amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;FILESEXTRAPATHS_prepend&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; := &amp;quot;${&lt;/span&gt;&lt;span&gt;THISDIR&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;}/files:&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As can be seen, the protocol specified isn&#39;t git, but file. Another simpler example is u-boot, where there is a need to apply a custom patch on top of Xilinx&#39;s u-boot
source and just the below in a recipe appending the original one.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;FILESEXTRAPATHS_prepend&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; := &amp;quot;${&lt;/span&gt;&lt;span&gt;THISDIR&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;}/files:&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;SRC_URI_append&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = &amp;quot;&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;    file://0001-configs-xilinx_zynqmp-Config-SD-and-eMMC-boot-for-GE.patch &lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also had to include a &lt;code&gt;rl78flash&lt;/code&gt; program which wasn&#39;t provided by any of the meta layers in Yocto and even that was easy. Looked at how some other recipes were written and came up with this and it just worked.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;SUMMARY&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = &amp;quot;RL78 Flash Tool&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;DESCRIPTION&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = &amp;quot;Software to program RL78 microcontrollers via Serial Bootloader&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;LICENSE&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = &amp;quot;MIT&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;LIC_FILES_CHKSUM&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = &amp;quot;file://${&lt;/span&gt;&lt;span&gt;COMMON_LICENSE_DIR&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;SRCREV&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = &amp;quot;d0f5f05fbbce0a278658ca0caf67f293dcd26ee3&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;SRC_URI&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = &amp;quot;git://github.com/msalau/rl78flash.git;protocol=https;branch=master &lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          file://rl78flash.patch &lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt;\&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;          &amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;S&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = &amp;quot;${&lt;/span&gt;&lt;span&gt;WORKDIR&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;}/git&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;EXTRA_OEMAKE&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = &amp;quot;&amp;#39;CC=${&lt;/span&gt;&lt;span&gt;CC&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;}&amp;#39; &amp;#39;CFLAGS=${&lt;/span&gt;&lt;span&gt;CFLAGS&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;}&amp;#39;&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;do_compile&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    oe_runmake&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;do_install&lt;/span&gt;&lt;span&gt;() {&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    install&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -d&lt;/span&gt;&lt;span&gt; ${D}${bindir}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;    install&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -m 0755&lt;/span&gt;&lt;span&gt; ${WORKDIR}&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;/git/rl78flash&lt;/span&gt;&lt;span&gt; ${D}${bindir}&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yocto by default uses &lt;code&gt;sysvinit&lt;/code&gt;, however, wanted to use systemd as init. Adding the below to &lt;code&gt;local.conf&lt;/code&gt; makes systemd as the init system.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;DISTRO_FEATURES_append&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = &amp;quot; systemd&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;DISTRO_FEATURES_BACKFILL_CONSIDERED&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; += &amp;quot;sysvinit&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;VIRTUAL-RUNTIME_init_manager&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = &amp;quot;systemd&amp;quot;&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;VIRTUAL-RUNTIME_initscripts&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; = &amp;quot;systemd-compat-units&amp;quot;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It has been a lot fun learning how to put together a board support package and Yocto has given so much flexibility.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Rust Run Series at the Bangalore Rust meetup group</title>
        <published>2018-12-02T00:00:00+00:00</published>
        <updated>2018-12-02T00:00:00+00:00</updated>
        
        <author>
          <name>Sanchayan Maity</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://sanchayanmaity.net/posts/rust-run/"/>
        <id>https://sanchayanmaity.net/posts/rust-run/</id>
        
        <content type="html" xml:base="https://sanchayanmaity.net/posts/rust-run/">&lt;p&gt;I took over the responsibility of being primary speaker at the &lt;a rel=&quot;external&quot; href=&quot;https://www.meetup.com/rustox/&quot;&gt;rustox&lt;/a&gt; meetup group in February 2018 from Ragini and Saifi who founded this group and used to host it every weekend. Have learned a lot from them.&lt;/p&gt;
&lt;p&gt;Saifi had envisioned a series on Rust topics for beginners, which we decided to continue. The goals for 2018 by him are outlined &lt;a rel=&quot;external&quot; href=&quot;https://medium.com/@rustox/rust-bangalore-2018-goals-f1f16397cd47&quot;&gt;here&lt;/a&gt;. However, it felt after a while catering to beginners alone and since there are always people coming on-board, no progress can be made beyond a certain point. There had already been a beginners series in 2017. With that in mind and after talking with Raj, who was now the organizer for sister group &lt;a rel=&quot;external&quot; href=&quot;https://www.meetup.com/fosscafe/&quot;&gt;FOSS Cafe&lt;/a&gt;, we decided that there would be a fundamental topic one week and the next week some crate or project could be discussed. And this would alternate and keep on continuing. This could cater to both beginners as well as those who were interested in some more intermediate level topics.&lt;/p&gt;
&lt;p&gt;With &lt;a rel=&quot;external&quot; href=&quot;https://reps.mozilla.org/u/jenal/&quot;&gt;Jyotsna Gupta&lt;/a&gt; also helping with the Mozilla and Rust swag, we decided to name this series as Rust Run. The following meetup events have been conducted as part of the series.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://www.meetup.com/rustox/events/250768637/&quot;&gt;Ownership, References &amp;amp; Borrowing&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://www.meetup.com/rustox/events/250768716/&quot;&gt;Raft Consensus Algorithm&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://www.meetup.com/rustox/events/250768752/&quot;&gt;Generics and Traits&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://www.meetup.com/rustox/events/250768766/&quot;&gt;Futures&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://www.meetup.com/rustox/events/250768799/&quot;&gt;Error handling in Rust&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://www.meetup.com/rustox/events/250768815/&quot;&gt;tokio&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://www.meetup.com/rustox/events/250768828/&quot;&gt;Lifetimes in Rust&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://www.meetup.com/rustox/events/250768886/&quot;&gt;Smart Pointers in Rust&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://www.meetup.com/rustox/events/250768950/&quot;&gt;Rocket Web Framework&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://www.meetup.com/rustox/events/250768992/&quot;&gt;Concurrency in Rust&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://www.meetup.com/rustox/events/250769067/&quot;&gt;Diesel&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;https://www.meetup.com/rustox/events/254812229/&quot;&gt;Flatbuffers&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A big thanks to &lt;a rel=&quot;external&quot; href=&quot;https://www.hackerearth.com/&quot;&gt;HackerEarth&lt;/a&gt; who have been forthcoming in providing the venue for meetups in last few months and also to &lt;a rel=&quot;external&quot; href=&quot;http://www.91springboard.com/&quot;&gt;91SpringBoard&lt;/a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https://www.axisbank.com/thoughtfactory/index.html&quot;&gt;ThoughtFactory&lt;/a&gt; where a lot of the earlier meetups were conducted. Here are some pictures from the meetups conducted at HackerEarth.&lt;/p&gt;
&lt;p&gt;From the meetup on tokio.
&lt;img src=&quot;/tokio.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;From the meetup on lifetimes.
&lt;img src=&quot;/lifetimes.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;From the meetup on Rocket.
&lt;img src=&quot;/rocket.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;From the meetup on Concurrency in Rust.
&lt;img src=&quot;/concurrency.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;From the meetup on Smart Pointers.
&lt;img src=&quot;/smartpointers.jpeg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>My experience as a speaker at meetup groups</title>
        <published>2018-10-08T00:00:00+00:00</published>
        <updated>2018-10-08T00:00:00+00:00</updated>
        
        <author>
          <name>Sanchayan Maity</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://sanchayanmaity.net/posts/experience-as-speaker-at-meetup/"/>
        <id>https://sanchayanmaity.net/posts/experience-as-speaker-at-meetup/</id>
        
        <content type="html" xml:base="https://sanchayanmaity.net/posts/experience-as-speaker-at-meetup/">&lt;p&gt;After joining the first meetup group and going on a regular basis, never thought about ending up being a speaker at those meetups. Joined the &lt;a rel=&quot;external&quot; href=&quot;https://www.meetup.com/rustox/&quot;&gt;rustox&lt;/a&gt; meetup group in May 2017 and have been a regular since then. This meetup group was started by Ragini and Saifi, two wonderful people. They used to conduct this meetup every Sunday morning and every Sunday morning ended up attending these meetups. Learned a lot from both of them. So when in the end of January 2018, they had to leave Bengaluru for a while for working on a project which they had taken for their own company, was asked to become the organizer and speaker. Had never thought of being a speaker and ended up speaking almost every other weekend.&lt;/p&gt;
&lt;p&gt;Saifi had envisioned a series on Rust topics for beginners. The goals for 2018 are outlined &lt;a rel=&quot;external&quot; href=&quot;https://medium.com/@rustox/rust-bangalore-2018-goals-f1f16397cd47&quot;&gt;here&lt;/a&gt;. However, it felt after a while that catering just to beginners and with people always coming on-board, no progress can be beyond a certain point. There had already been a beginners series in 2017. With that in mind and after talking with Raj, who was now the organizer for sister group &lt;a rel=&quot;external&quot; href=&quot;https://www.meetup.com/fosscafe/&quot;&gt;FOSS Cafe&lt;/a&gt;, it was decided that there would be a fundamental topic one week and the next week some crate or project would serve as the topic of discussion or presentation. And this would alternate and keep on continuing. This also seemed in-line with the bi-modal approach which Saifi had envisioned. The first project looked at was &lt;a rel=&quot;external&quot; href=&quot;https://www.getgutenberg.io/&quot;&gt;Gutenberg&lt;/a&gt;, a static website engine in Rust, which is also what this blog has been generated with (at the time of writing at least). On the way along with fundamental topics, crates/projects like Rocket, Diesel, Crossbeam, mio, tokio, and futures were covered.&lt;/p&gt;
&lt;p&gt;There is an excellent write-up &lt;a rel=&quot;external&quot; href=&quot;https://dev.to/aspittel/public-speaking-as-a-developer-2ihj&quot;&gt;here&lt;/a&gt; by &lt;a rel=&quot;external&quot; href=&quot;https://twitter.com/ASpittel&quot;&gt;Ali Spittel&lt;/a&gt; on why you should consider public speaking as a developer. Personally, have had found two motivations for organizing and speaking at meetup groups. First, it acts as a great way to reinforce what has been learned in the process of preparing for a meetup talk. It can also be something one has been interested in learning and having spend a certain amount of time on a topic, decided to speak on it. This is what was being done for the &lt;a rel=&quot;external&quot; href=&quot;https://www.meetup.com/Bangalore-Functional-Programmers-Meetup/&quot;&gt;Functional Programmers Meetup&lt;/a&gt; as well, where I frequently speak on a topic in Haskell. Often I found, that the understanding has improved after giving the talk or I didn&#39;t understand something, but, during the discussion process it became much more clear. Or someone from the audience has helped understand. Second, I have met some interesting and wonderful people along the way. It&#39;s always nice to meet people who are passionate about something and spend their time on learning and picking it up. People with different experiences from different domains.&lt;/p&gt;
&lt;p&gt;However, it&#39;s not all hunky dory. One of the challenges with organizing such meetups is engaging people. Am pretty sure am not great at this, however, I try. Different people have different interests and it&#39;s not always possible to cater to everyone. Also, Rust though a great language has a steeper learning curve in comparison to something like Python. Unless one is willing to invest some time on a continuous basis, it might be difficult to pick up depending on what kind of a background one is coming from.&lt;/p&gt;
&lt;p&gt;Sometimes, one gets asked a question which might be difficult to answer objectively. The question was &quot;What&#39;s the killer app for Rust?&quot; or it was something definitely similar. Rust stands on the basis of what it offers and purely on technical merit, not to mention the great community around it. Hats off to Mozilla, Steve Klabnik, Aaron Turon and various others who have been working on Rust. Another difficulty is only one third of the people who RSVP actually turn up and having a consistent set of 10-15 members willing to speak or contribute code wise has been next to impossible.&lt;/p&gt;
&lt;p&gt;Now, that 2018 is coming to a close, am wondering what the plan for 2019 should be to take this forward and improve on what has been done in 2018. Having seen this &lt;a rel=&quot;external&quot; href=&quot;https://www.youtube.com/watch?v=2xyZeovFqCA&quot;&gt;talk&lt;/a&gt; recently, think going forward, should try and understand how something like mio or Diesel actually works and has been implemented. The aim should to be producers and contributors and not just consumers. And last but not the least a big thanks to &lt;a rel=&quot;external&quot; href=&quot;https://www.hackerearth.com/&quot;&gt;HackerEarth&lt;/a&gt; who have been forthcoming in providing us the venue for meetups in last few months and also to &lt;a rel=&quot;external&quot; href=&quot;http://www.91springboard.com/&quot;&gt;91SpringBoard&lt;/a&gt; and &lt;a rel=&quot;external&quot; href=&quot;https://www.axisbank.com/thoughtfactory/index.html&quot;&gt;ThoughtFactory&lt;/a&gt; where a lot of earlier meetups were conducted.&lt;/p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Using OS containers for OpenEmbedded build</title>
        <published>2015-06-02T00:00:00+00:00</published>
        <updated>2015-06-02T00:00:00+00:00</updated>
        
        <author>
          <name>Sanchayan Maity</name>
        </author>
        
        <link rel="alternate" type="text/html" href="https://sanchayanmaity.net/posts/using-os-containers-for-openembedded-build/"/>
        <id>https://sanchayanmaity.net/posts/using-os-containers-for-openembedded-build/</id>
        
        <content type="html" xml:base="https://sanchayanmaity.net/posts/using-os-containers-for-openembedded-build/">&lt;p&gt;As a user of Arch Linux on laptop and on the server which gets used for OpenEmbedded builds, OpenEmbedded doesn&#39;t exactly like rolling release distros. Somehow for whatever reason, current builds just fail. Remember facing the problem when using Arch and learning OpenEmbedded iin the early days which lead to the first OpenEmbedded post. Why? Not having the time to debug such a thing, there was another solution at hand.&lt;/p&gt;
&lt;p&gt;The solution is to use a &lt;code&gt;chroot&lt;/code&gt; jail or when having systemd as init, that would be resorting to the use of &lt;code&gt;systemd-nspawn&lt;/code&gt;. So lets get on how to set up an environment which can be used for builds. Assuming one has yaourt installed,&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;yaourt&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -S&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; debootstrap&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;mkdir&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; ~/debian-root&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; debootstrap&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; --arch=amd64 --variant=minbase&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; jessie ~/debian-root&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;sudo&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; systemd-nspawn&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -D&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; debian-root&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The third command is gonna take a while. After running the last command, one would be inside the &lt;code&gt;chroot&lt;/code&gt; jail as a root user. After that run the following.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;apt-get&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; install update&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;apt-get&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; install sudo&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;adduser&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -uid 1000 -gid 100&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; username&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;visudo&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;su&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; username&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Assume you know what to add after running &lt;code&gt;visudo&lt;/code&gt;, basically add yourself to the &lt;code&gt;sudoers&lt;/code&gt; file. To get the user id and group id for the &lt;code&gt;adduser&lt;/code&gt; command, run &quot;id&quot; on host. The last command drops you in the home directory for the newly created user. Whenever wanting to work on OpenEmbedded, just use &lt;code&gt;systemd-nspawn&lt;/code&gt; to log in to the Debian environment. This environment can be kept for as long one likes to maintain the build setup while the normal user space can be updated without fear of breaking the build. One can replicate the exact Debian environment by just copying the complete Debian root directory using something like &lt;code&gt;rsync&lt;/code&gt; to any number of your machines.&lt;/p&gt;
&lt;p&gt;Also do note that Debian isn&#39;t the only one you can use. One can do this for Fedora, Arch, and probably other distros too.&lt;/p&gt;
&lt;p&gt;Output from the Debian root environment.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;sanchayan@debian-root:~/oe-core/build$&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; uname&lt;/span&gt;&lt;span style=&quot;color: #AE81FF;&quot;&gt; -a&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;Linux&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; debian-root 4.0.0-ck1-bfs-ck+&lt;/span&gt;&lt;span style=&quot;color: #88846F;&quot;&gt; #8 SMP PREEMPT Wed Apr 29 11:35:34 IST 2015 x86_64 GNU/Linux&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;sanchayan@debian-root:~/oe-core/build$&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; pwd&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;/home/sanchayan/oe-core/build&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Output of &lt;code&gt;machinectl&lt;/code&gt; from the host.&lt;/p&gt;
&lt;pre class=&quot;giallo&quot; style=&quot;color: #F8F8F2; background-color: #272822;&quot; &gt;&lt;code data-lang=&quot;shellscript&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;machinectl&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;MACHINE&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt;     CLASS     SERVICE&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;debian-root&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; container nspawn&lt;/span&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;/span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span style=&quot;color: #A6E22E;&quot;&gt;1&lt;/span&gt;&lt;span style=&quot;color: #E6DB74;&quot;&gt; machines listed.&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a rel=&quot;external&quot; href=&quot;http://0pointer.net/blog/archives.html&quot;&gt;systemd for Administrators&lt;/a&gt; series should be interesting to you.&lt;/p&gt;
&lt;p&gt;Do have a look at the man pages for &lt;code&gt;systemd-nspawn&lt;/code&gt; and &lt;code&gt;machinectl&lt;/code&gt;.&lt;/p&gt;
</content>
        
    </entry>
</feed>
