<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>C&#43;&#43; on kistu</title>
  <link rel="alternate" href="/tags/c&#43;&#43;/" />
  <link rel="self" href="/tags/c&#43;&#43;/index.xml" />
  <subtitle>Recent content in C&#43;&#43; on kistu</subtitle>
  <id>/tags/c&#43;&#43;/</id>
  <generator uri="http://gohugo.io" version="0.124.0">Hugo</generator>
  <language>en</language>
  <updated>2026-02-25T22:24:26+02:00</updated>
  <author>
    
    
  </author>
  
      <entry>
        <title>Audio Engines in C&#43;&#43;</title>
        <link rel="alternate" href="/posts/004-audio-engines-in-c&#43;&#43;/" />
        <id>/posts/004-audio-engines-in-c&#43;&#43;/</id>
        <published>2026-02-25T22:24:26+02:00</published>
        <updated>2026-03-26T21:18:27+02:00</updated>
        <summary type="html">Context Rhythmbox-Reloaded is a C++ application that needs to play audio files. There are libraries that handle this - they simply need to be included, initialized and used. miniaudio is easy to integrate, but has file format limitations. libvlc can support almost any format, but bundling it with the application impacts size and performance. Dynamic linking addresses this issue, but creates a requirement for external dependencies. As a compromise, the application may try to use libvlc, but fall back to miniaudio.</summary>
          <content type="html"><![CDATA[<h1 id="context">Context</h1>
<p><a href="https://git.kistu.dev/kistu/rhythmbox-reloaded-desktop">Rhythmbox-Reloaded</a> is a C++ application that needs to play audio files. There are libraries that handle this - they simply need to be included, initialized and used. <code>miniaudio</code> is easy to integrate, but has file format limitations. <code>libvlc</code> can support almost any format, but bundling it with the application impacts size and performance. Dynamic linking addresses this issue, but creates a requirement for external dependencies. As a compromise, the application may try to use <code>libvlc</code>, but fall back to <code>miniaudio</code>.</p>
<h1 id="miniaudio">Miniaudio</h1>
<p><a href="https://miniaud.io/">Miniaudio</a> is an audio playback library for C and C++; it is made up of a single source file without external dependencies.</p>
<p>To use the library, download the header file <a href="https://raw.githubusercontent.com/mackron/miniaudio/master/miniaudio.h">miniaudio.h</a>.</p>
<p>To test the library by playing a file, create <code>ma-test.cpp</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="cp">#define MINIAUDIO_IMPLEMENTATION
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;miniaudio.h&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">main</span><span class="p">(){</span>
</span></span><span class="line"><span class="cl">	<span class="c1">// Miniaudio variables
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>	<span class="n">ma_engine</span> <span class="n">engine</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">ma_result</span> <span class="n">result</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="n">ma_sound</span> <span class="n">sound</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="c1">// Initialize engine
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>	<span class="n">result</span> <span class="o">=</span> <span class="n">ma_engine_init</span><span class="p">(</span><span class="nb">NULL</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">engine</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">	<span class="k">if</span> <span class="p">(</span><span class="n">result</span> <span class="o">==</span> <span class="n">MA_SUCCESS</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">		<span class="c1">// Load file
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>		<span class="n">result</span> <span class="o">=</span> <span class="n">ma_sound_init_from_file</span><span class="p">(</span><span class="o">&amp;</span><span class="n">engine</span><span class="p">,</span> <span class="s">&#34;file.mp3&#34;</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">sound</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">		<span class="k">if</span> <span class="p">(</span><span class="n">result</span> <span class="o">==</span> <span class="n">MA_SUCCESS</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">			<span class="c1">// Start playback
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>			<span class="n">ma_sound_start</span><span class="p">(</span><span class="o">&amp;</span><span class="n">sound</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">			<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;Playing file.</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">			<span class="c1">// Wait until completion
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>			<span class="k">while</span><span class="p">(</span><span class="o">!</span><span class="n">ma_sound_at_end</span><span class="p">(</span><span class="o">&amp;</span><span class="n">sound</span><span class="p">)){</span>
</span></span><span class="line"><span class="cl">				<span class="n">ma_sleep</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">			<span class="p">}</span>
</span></span><span class="line"><span class="cl">			<span class="n">ma_sound_uninit</span><span class="p">(</span><span class="o">&amp;</span><span class="n">sound</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">			<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;Playback completed.</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">		<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">			<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;Failed to load file.</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">		<span class="p">}</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">		<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;Failed to initialize file.</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">	<span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Compile and run:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">g++ ma-test.cpp -o ma-test.o
</span></span><span class="line"><span class="cl">./ma-test.o
</span></span></code></pre></div><blockquote>
<p>Ensure the header file <code>miniaudio.h</code> and audio file <code>file.mp3</code> are in the same folder as the above source code file.</p>
</blockquote>
<p>The high level API has built in support for WAV, MP3 and FLAC - other formats require more complex configuration with the low level API. <sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> If support for an extensive list of audio formats is required, <code>libvlc</code> may be better suited.</p>
<h1 id="libvlc">libvlc</h1>
<p><a href="https://code.videolan.org/videolan/libvlc">libvlc</a> is a C library that is the core engine of the VLC media player. VideoLAN provides official C++ bindings <a href="https://code.videolan.org/videolan/libvlcpp">(libvlcpp)</a> that acts as a wrapper for libvlc. The bindings consist of header files; only the <code>vlcpp</code> folder - containing several .hpp files - is required from the repository: <a href="https://code.videolan.org/videolan/libvlcpp">https://code.videolan.org/videolan/libvlcpp</a>.</p>
<blockquote>
<p>VLC and libvlc are required dependencies. Some sources of VLC may not expose libvlc as a library. Refer to the VLC installation guides for your particular system.</p>
</blockquote>
<p>Once libvlc is accessible and the <code>vlcpp</code> folder has been copied to the current folder, the engine can be tested; create <code>vlc-test.cpp</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-c++" data-lang="c++"><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&#34;vlcpp/vlc.hpp&#34;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;unistd.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">main</span><span class="p">(){</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="c1">// VLC variables
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">VLC</span><span class="o">::</span><span class="n">Instance</span> <span class="n">m_instance</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">VLC</span><span class="o">::</span><span class="n">MediaPlayer</span> <span class="n">m_player</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">VLC</span><span class="o">::</span><span class="n">Media</span> <span class="n">m_media</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">// Initialize with video disabled
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="k">static</span> <span class="k">const</span> <span class="kt">char</span><span class="o">*</span> <span class="k">const</span> <span class="n">vlc_args</span><span class="p">[]</span> <span class="p">{</span><span class="s">&#34;--no-video&#34;</span><span class="p">,</span> <span class="s">&#34;--vout=dummy&#34;</span><span class="p">};</span>
</span></span><span class="line"><span class="cl">    <span class="n">m_instance</span> <span class="o">=</span> <span class="n">VLC</span><span class="o">::</span><span class="n">Instance</span><span class="p">(</span><span class="kt">int</span><span class="p">(</span><span class="k">sizeof</span><span class="p">(</span><span class="n">vlc_args</span><span class="p">)</span><span class="o">/</span><span class="k">sizeof</span><span class="p">(</span><span class="n">vlc_args</span><span class="p">[</span><span class="mi">0</span><span class="p">])),</span> <span class="n">vlc_args</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">m_player</span> <span class="o">=</span> <span class="n">VLC</span><span class="o">::</span><span class="n">MediaPlayer</span><span class="p">(</span><span class="n">m_instance</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">m_media</span> <span class="o">=</span> <span class="n">VLC</span><span class="o">::</span><span class="n">Media</span><span class="p">(</span><span class="n">m_instance</span><span class="p">,</span> <span class="s">&#34;file.mp3&#34;</span><span class="p">,</span> <span class="n">VLC</span><span class="o">::</span><span class="n">Media</span><span class="o">::</span><span class="n">FromPath</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">m_player</span><span class="p">.</span><span class="n">setMedia</span><span class="p">(</span><span class="n">m_media</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">// Start playback
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="k">if</span> <span class="p">(</span><span class="n">m_player</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">m_player</span><span class="p">.</span><span class="n">play</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// Wait for playback to start, then finish
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="k">while</span> <span class="p">(</span><span class="o">!</span><span class="n">m_player</span><span class="p">.</span><span class="n">isPlaying</span><span class="p">()){</span> <span class="n">usleep</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">while</span> <span class="p">(</span><span class="n">m_player</span><span class="p">.</span><span class="n">isPlaying</span><span class="p">())</span> <span class="p">{</span> <span class="n">usleep</span><span class="p">(</span><span class="mi">10</span><span class="p">);</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>libvlc must be linked when compiling:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">g++ -lvlc vlc-test.cpp -o vlc-test.o
</span></span><span class="line"><span class="cl">./vlc-test.o
</span></span></code></pre></div><blockquote>
<p>If you need to package the application as an AppImage, you must exclude libvlc when building. VLC initialization unexpectedly fails with partial vlc installations (missing some plugins) and including the full installation would be quite inefficient - it is better to dynamically link.</p>
</blockquote>
<h1 id="fallback">Fallback</h1>
<p>It would be beneficial if the application could retain some functionality even if <code>libvlc</code> is unavailable. When using <code>libvlc</code> by <code>#include &lt;vlcpp/vlc.hpp&gt;</code>, the application does not start without libvlc.</p>
<p>Using preprocessor directives only works for compilation. The developer machine can be required to have vlc installed, but this doesn&rsquo;t solve the runtime issue.</p>
<p>Another option is to load the library at runtime using <code>dlopen</code> or <code>LoadLibrary</code>, but since <code>libvlcpp</code> is being used as a binding, this doesn&rsquo;t seem easily possible.</p>
<p>Currently, fallback is not supported. Two build version may be offered - one using <code>miniaudio</code> and the other <code>libvlc</code>. An integrated version would be prefered.</p>
<div class="footnotes" role="doc-endnotes">
<hr>
<ol>
<li id="fn:1">
<p><a href="https://miniaud.io/docs/manual/index.html#Decoding">https://miniaud.io/docs/manual/index.html#Decoding</a>&#160;<a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#x21a9;&#xfe0e;</a></p>
</li>
</ol>
</div>
]]></content>
      </entry>

</feed>


