<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Knowledge Base (Posts about music)</title><link>https://bgstack15.ddns.net/blog/</link><description></description><atom:link href="https://bgstack15.ddns.net/blog/categories/music.xml" rel="self" type="application/rss+xml"></atom:link><language>en</language><copyright>Contents © 2025 &lt;a href="mailto:bgstack15@gmail.com"&gt;bgstack15&lt;/a&gt; 
&lt;a rel="license" href="https://www.gnu.org/licenses/gpl-3.0.html"&gt;
&lt;img alt="GNU General Public License v3.0"
style="border-width:0; margin-bottom:12px;"
src="https://bgstack15.ddns.net/.images/gplv3-127x51.png"&gt;&lt;/a&gt;</copyright><lastBuildDate>Thu, 12 Jun 2025 12:45:42 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>soundcore 2 review and notes</title><link>https://bgstack15.ddns.net/blog/posts/2025/06/12/soundcore-2-review-and-notes/</link><dc:creator>bgstack15</dc:creator><description>&lt;p&gt;The product in question is bluetooth speaker &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/www.amazon.com/Anker-Soundcore-Bluetooth-Exclusive-Water-Resistant/dp/B074NS9P2J?th=1"&gt;SoundCore 2 A3105&lt;/a&gt; which was $44.99ish before tax.&lt;/p&gt;
&lt;p&gt;I am not getting paid or compensated in any way for this information. If you wish to change that, please contact me!&lt;/p&gt;
&lt;h2&gt;Behavior of button play/pause&lt;/h2&gt;
&lt;p&gt;Here is some additional info not in the manual about the &lt;strong&gt;play/pause&lt;/strong&gt; button:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;3 times: restart this track&lt;/li&gt;
&lt;li&gt;4 times: skip back&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is what is published in the manual.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1 time: play/pause&lt;/li&gt;
&lt;li&gt;2 times: skip forward&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Thoughts&lt;/h2&gt;
&lt;p&gt;Bass doesn't sound as thorough as JBL Flip 3, but that one was damaged or broken and kept freezing up for no good reason.&lt;/p&gt;
&lt;h2&gt;Links&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/support.soundcore.com/s/product/a085g000000Nly7AAC/soundcore-2"&gt;product page from manufacturer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/support.soundcore.com/s/downloads?location=/000021515/en_US/000021515.pdf"&gt;User guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/support.soundcore.com/s/downloads?location=/000004369/en_US/000004369.pdf"&gt;Manual&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/support.soundcore.com/s/downloads?location=/000004801/en_US/000004801.pdf"&gt;Quick start guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Auxiliary notes&lt;/h2&gt;
&lt;p&gt;Internet search &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/duckduckgo.com/?q=bluetooth+speaker+skip+backward"&gt;bluetooth speaker skip backward&lt;/a&gt; showed that some bluetooth speakers skip back when you press play/pause 3+ times. My research shows this can work on the Soundcore 2 speaker!&lt;/p&gt;
&lt;h2&gt;After more time&lt;/h2&gt;
&lt;p&gt;Sometimes the words sound a little mushy/slurred. Overall I'd say this is a rather disappointing bluetooth speaker. It also suffers from the random freezing as my old device. Maybe I have a jellyfin problem. So I'm still just using the much clearer (when it's working) JBL Flip 3.&lt;/p&gt;</description><category>audio</category><category>music</category><guid>https://bgstack15.ddns.net/blog/posts/2025/06/12/soundcore-2-review-and-notes/</guid><pubDate>Thu, 12 Jun 2025 12:42:00 GMT</pubDate></item><item><title>pacpl in Devuan and gnudb</title><link>https://bgstack15.ddns.net/blog/posts/2023/10/22/pacpl-in-devuan-and-gnudb/</link><dc:creator>bgstack15</dc:creator><description>&lt;p&gt;I have decided to use headless tools to rip my audio CDs, because that's easier to automate. I looked into options other than the nice and simple but graphical tool &lt;a href="https://bgstack15.ddns.net/blog/outbound/http:/littlesvr.ca/asunder/"&gt;asunder&lt;/a&gt;, and found the Debian list for &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/wiki.debian.org/Ripping"&gt;ripping&lt;/a&gt; software.&lt;/p&gt;
&lt;p&gt;I tested out pacpl, which works well enough. However, as tends to happen in Debian, the tool points to cddb.org which is long gone. The open source folks use &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/gnudb.org"&gt;gnudb.org&lt;/a&gt; nowadays, but this is not reflected in the Devuan unstable package of gnudb. So you just have to adjust &lt;code&gt;/etc/pacpl/pacpl.conf&lt;/code&gt; with this oneliner if you use my &lt;a href="https://bgstack15.ddns.net/blog/outbound/https:/build.opensuse.org/package/show/home:bgstack15/bgscripts"&gt;bgscripts&lt;/a&gt; package:&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;sudo python3 /usr/libexec/bgscripts/py/modconf.py -a -l '=' /etc/pacpl/pacpl.conf set CDDB_HOST gnudb.gnudb.org
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you don't use that, you need to set variable &lt;code&gt;CDDB_HOST&lt;/code&gt; to &lt;code&gt;gnudb.gnudb.org&lt;/code&gt;. Hopefully that was obvious.&lt;/p&gt;</description><category>cd</category><category>music</category><category>oneliner</category><guid>https://bgstack15.ddns.net/blog/posts/2023/10/22/pacpl-in-devuan-and-gnudb/</guid><pubDate>Sun, 22 Oct 2023 12:52:43 GMT</pubDate></item><item><title>Find average volume change needed for album</title><link>https://bgstack15.ddns.net/blog/posts/2023/08/19/find-average-volume-change-needed-for-album/</link><dc:creator>bgstack15</dc:creator><description>&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;x=0 ; for word in *.mp3 ; do x=$((x+1)) ; ffmpeg -i "&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;" -af "volumedetect" -vn -sn -dn -f null /dev/null 2&amp;gt;&lt;span class="err"&gt;&amp;amp;&lt;/span&gt;1 | awk "BEGIN{OFS=\",\"} /mean_volume/{a=\$5} /max_volume/{b=\$5} END{print a,b}" | sed -r -e "s/^/&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;,/;" ; done
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;And then I saw the whole list of max and mean volumes. So my minimum max_volume is &lt;code&gt;-8.3&lt;/code&gt;, so I need to add this amount to each file. I think ffmpeg does not use fractional decibels, so I chose 9.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;x=0 ; time for word in *.mp3 ; do x=$((x+1)) ; new="new&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;" ; ffmpeg -i "&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;" -af "volume=9dB" "&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;" ; done
&lt;/pre&gt;&lt;/div&gt;</description><category>audio</category><category>ffmpeg</category><category>mp3</category><category>music</category><category>volume</category><guid>https://bgstack15.ddns.net/blog/posts/2023/08/19/find-average-volume-change-needed-for-album/</guid><pubDate>Sat, 19 Aug 2023 12:36:19 GMT</pubDate></item><item><title>Shell alias: hide-song</title><link>https://bgstack15.ddns.net/blog/posts/2023/06/21/shell-alias-hide-song/</link><dc:creator>bgstack15</dc:creator><description>&lt;p&gt;I have a number of music albums in their entirety: I am a completionist! But that doesn't mean I like every song in the album. Rather than delete those bits, I set them aside. Gzipping alone isn't enough because vlc is smart enough to still play the audio. So I base64 them, and then gzip them (and then &lt;a href="https://bgstack15.ddns.net/blog/outbound/http:/www.montypython.50webs.com/scripts/Holy_Grail/Scene13.htm"&gt;sink them into the swamp&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;And then I wrote a shell function to do this for me, preserving timestamp. I like metadata; I don't like data.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;hide-song() { _i="&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;" ; test ! -f "&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;_i&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;" &lt;span class="err"&gt;&amp;amp;&amp;amp;&lt;/span&gt; return 1 ; &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;"&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;_i&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;" base64 &amp;gt;"&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;_i&lt;/span&gt;&lt;span class="o"&gt;%%.&lt;/span&gt;&lt;span class="n"&gt;mp3&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;.b64" &lt;span class="err"&gt;&amp;amp;&amp;amp;&lt;/span&gt; touch --reference "&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;_i&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;" "&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;_i&lt;/span&gt;&lt;span class="o"&gt;%%.&lt;/span&gt;&lt;span class="n"&gt;mp3&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;.b64" &lt;span class="err"&gt;&amp;amp;&amp;amp;&lt;/span&gt; gzip "&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;_i&lt;/span&gt;&lt;span class="o"&gt;%%.&lt;/span&gt;&lt;span class="n"&gt;mp3&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;.b64" &lt;span class="err"&gt;&amp;amp;&amp;amp;&lt;/span&gt; \rm "&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;_i&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;" ; }
unhide-song() { _i="&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;" ; gunzip "&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;_i&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;" &lt;span class="err"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;"&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;_i&lt;/span&gt;&lt;span class="o"&gt;%%.&lt;/span&gt;&lt;span class="n"&gt;gz&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;" base64 -d &amp;gt; "&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;_i&lt;/span&gt;&lt;span class="o"&gt;%%.&lt;/span&gt;&lt;span class="n"&gt;b64&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gz&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;.mp3" &lt;span class="err"&gt;&amp;amp;&amp;amp;&lt;/span&gt; touch --reference "&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;_i&lt;/span&gt;&lt;span class="o"&gt;%%.&lt;/span&gt;&lt;span class="n"&gt;gz&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;" "&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;_i&lt;/span&gt;&lt;span class="o"&gt;%%.&lt;/span&gt;&lt;span class="n"&gt;b64&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gz&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;.mp3" &lt;span class="err"&gt;&amp;amp;&amp;amp;&lt;/span&gt; \rm "&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;_i&lt;/span&gt;&lt;span class="o"&gt;%%.&lt;/span&gt;&lt;span class="n"&gt;gz&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;" ; }
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Because I need more word-count, let's explain these.&lt;/p&gt;
&lt;div class="code"&gt;&lt;pre class="code literal-block"&gt;hide-song() {
    _i="&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;"
    test ! -f "&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;_i&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;" &lt;span class="err"&gt;&amp;amp;&amp;amp;&lt;/span&gt; return 1
    &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;"&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;_i&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;" base64 &amp;gt;"&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;_i&lt;/span&gt;&lt;span class="o"&gt;%%.&lt;/span&gt;&lt;span class="n"&gt;mp3&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;.b64" &lt;span class="err"&gt;&amp;amp;&amp;amp;&lt;/span&gt; \
        touch --reference "&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;_i&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;" "&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;_i&lt;/span&gt;&lt;span class="o"&gt;%%.&lt;/span&gt;&lt;span class="n"&gt;mp3&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;.b64" &lt;span class="err"&gt;&amp;amp;&amp;amp;&lt;/span&gt; \
        gzip "&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;_i&lt;/span&gt;&lt;span class="o"&gt;%%.&lt;/span&gt;&lt;span class="n"&gt;mp3&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;.b64" &lt;span class="err"&gt;&amp;amp;&amp;amp;&lt;/span&gt; \
        \rm "&lt;span class="cp"&gt;${&lt;/span&gt;&lt;span class="n"&gt;_i&lt;/span&gt;&lt;span class="cp"&gt;}&lt;/span&gt;"
}
&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Line 2 sets a variable, and notably not a bash &lt;code&gt;local&lt;/code&gt; variable, but I like to use a single underscore to help avoid collisions. I like to avoid bashisms, never mind this is in my bash profile.&lt;/p&gt;
&lt;p&gt;Line 3 fails quietly but with an error code. Maybe it should throw a warning. I suppose the -f makes sure it is a real file, and not a symlink and not a directory so it's pulling double duty.&lt;/p&gt;
&lt;p&gt;Line 4 base64s the file to &lt;code&gt;file.b64&lt;/code&gt;. And yes, I'm anticipating the file has a .mp3 extension. Adapt to your own needs, detail-oriented people!&lt;/p&gt;
&lt;p&gt;Line 5 sets the timestamp of the new file to match the original file. (Yes, I don't like bashisms, but GNUisms are perfectly acceptable.)&lt;/p&gt;
&lt;p&gt;Line 6 gzips &lt;code&gt;file.b64&lt;/code&gt;, which notably preserves the timestamp in my GNU userland. I hardly use gzip without tar, but I guess I do here.&lt;/p&gt;
&lt;p&gt;Line 7 deletes the original file. Note the leading slash to avoid any aliases and just run &lt;code&gt;rm&lt;/code&gt;. And of course note that the rm happens only if the preceding commands are all successful (&lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; being the logical &lt;code&gt;and&lt;/code&gt;).&lt;/p&gt;</description><category>alias</category><category>gzip</category><category>mp3</category><category>music</category><category>shell</category><guid>https://bgstack15.ddns.net/blog/posts/2023/06/21/shell-alias-hide-song/</guid><pubDate>Wed, 21 Jun 2023 12:56:22 GMT</pubDate></item></channel></rss>