Jekyll2023-01-21T17:42:28-08:00https://bencholmes.github.io/feed.xmlBen HolmesAudio Hardware EngineerBen HolmesCounting the number of colour pages in a PDF2019-03-27T00:00:00-07:002019-03-27T00:00:00-07:00https://bencholmes.github.io/posts/2019/counting-colour-pages-pdf<p>This is just a little aside from the audio focus of this blog. Recently I completed my thesis for my PhD, which involves a lot of costly printing. Many printers charge one rate for black & white pages, and a separate, much higher rate for colour pages. As a result I wanted to anticipate how much one printing of the thesis would cost and so needed to know:</p>
<ul>
<li>The number of pages in the thesis</li>
<li>How many of these are colour, and</li>
<li>How many of these are black & white</li>
</ul>
<p>Performing this task on a pdf file was not immediately clear to me. Thankfully this is a well trodden path so the answer was readily available after a bit of searching and compiling, but I am writing it here so that anyone going down the same path doesn’t have to do the same.</p>
<p>The solution presented here uses a <strong>shell script</strong>, written for <strong>bash</strong>. This was run in the <strong>terminal</strong> on <strong>macOS</strong> High Sierra, but should be portable for bash terminals. The target document is a <strong>pdf</strong> as generated by <strong>LaTeX</strong>.</p>
<p>The script requires <a href="https://www.ghostscript.com/">ghostscript</a> to analyse the pdf page colour, this should be installed anyway with your LaTeX distribution, and uses <a href="https://forensicswiki.org/wiki/Pdfinfo">pdfinfo</a> so won’t run on Windows unfortunately!</p>
<h2 id="full-script">Full script</h2>
<p>For those who just want the code, here it is in a github gist:</p>
<script src="https://gist.github.com/bencholmes/3c9279d9f24758a0bbf084eecf836b2d.js"></script>
<h2 id="usage">Usage</h2>
<p>I wanted to design a shell script which I could call with a single argument, the file name, and receive the total number of pages and the number of colour/black & white pages. To do this I made a file called <code class="language-plaintext highlighter-rouge">count_colour_pages.sh</code> in which I wrote the shell script. This file needs to be on your <code class="language-plaintext highlighter-rouge">$PATH</code> to ensure you can call it anywhere in your file system.</p>
<p>The output is then three lines in the terminal reporting the desired properties of the pdf document.</p>
<p>An example:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>iMac: thesis-latex$ count_colour_pages.sh main.pdf
Number of pages: 213
Number of b&w: 141
Number of colour: 72
</code></pre></div></div>
<p>where <code class="language-plaintext highlighter-rouge">main.pdf</code> is my compiled LaTeX document. Despite the ridiculous length of theses, only around 1/3rd of this one has any colour on the page, which saved me a bunch when printing.</p>Ben HolmesThis is just a little aside from the audio focus of this blog. Recently I completed my thesis for my PhD, which involves a lot of costly printing. Many printers charge one rate for black & white pages, and a separate, much higher rate for colour pages. As a result I wanted to anticipate how much one printing of the thesis would cost and so needed to know:Measurement Gotchas: systematic error when averaging2018-04-06T00:00:00-07:002018-04-06T00:00:00-07:00https://bencholmes.github.io/posts/2018/04/measurement-gotchas-averaging<p>When trying to capture a clean signal from an electronic circuit, a popular strategy is to use averaging. The circuit is driven by the same signal repeatedly creating a set of output signals which can then be averaged, thus reducing noise. I’ve used this technique a lot in the measurement step of my work on training physical models on measured data (see <a href="http://benholmes.co.uk/publication/2015-12-01-Physical%20model%20parameter%20optimisation">my DAFx-16 paper</a> for more information).</p>
<p>One factor that is important to remember during the averaging process is the transient response of the circuit. If the circuit features large valued energy storing components, the transient response can feature long decay times. If the decay time is significant when compared to the length of the signal then the next time you take an average it can be skewed by the previous repeat.</p>
<p><img src="/images/rc-circuit.png" width="30%" alt="RC circuit" align="middle" /></p>
<p>Let’s say we’re trying to model the pictured RC circuit. To do this we drive the circuit with a wide-band signal and compare the measurements to a model and see how good the fit is. The time constant of the circuit is given by</p>
\[\tau = RC = 5\ \mathrm{k\Omega} \times 1\ \mathrm{\mu F} = 5\ \mathrm{ms}\]
<p>Driving this circuit with a 10ms windowed multi-sine signal consisting of integer multiples of 100 Hz from 1 to 10, the result is the following:</p>
<p><img src="/images/rc-averaging-error.png" alt="RC averaging error" /></p>
<p>The match between the model and the measurement in the first period is close. However in the second period there is a large discrepancy caused by the overlap of the transient decay from the previous period. If we were to try and fit the model to the average of the two periods, it would appear that there is something significantly wrong with the model!</p>
<p>By zero-padding the end of the signal, the transient decay can be mitigated:</p>
<p><img src="/images/rc-averaging-error-lengthened.png" alt="RC reduced error" /></p>
<p>The input signal has had 30 ms of zero-padding added to it and there is still some error in the start of the signal. Adding 30 ms of zero-padding has however increased the measurement length by a factor of 4. Depending on the number of averages required, this can cause problems not only with the duration of the measurements, but also with the amount of data recorded.</p>
<p>Fortunately this issues is easy to identify if you are aware of it, so the next time you’re averaging a measurement and you see a deviation from the expected starting values of your measurement, try inspecting the first period of your signal to see if the error is present there first.</p>Ben HolmesWhen trying to capture a clean signal from an electronic circuit, a popular strategy is to use averaging. The circuit is driven by the same signal repeatedly creating a set of output signals which can then be averaged, thus reducing noise. I’ve used this technique a lot in the measurement step of my work on training physical models on measured data (see my DAFx-16 paper for more information).Plotting the FFT of a voltage signal2018-04-06T00:00:00-07:002018-04-06T00:00:00-07:00https://bencholmes.github.io/posts/2018/05/plotting-voltage-fft<p>Plotting a signal in the frequency domain is a fundamental analysis tool which can provide great insight into the signal’s behaviour. Something I have struggled with in the past is getting the units correct such that the amplitude response of the frequency-domain representation has physical significance. In this blog post I aim to outline how to properly find useful units with which to represent voltage signals.</p>
<h2 id="testcase">Testcase</h2>
<p>To illustrate the methods in this post, a voltage signal of two sine waves and a DC offset will be used:</p>
<table>
<tbody>
<tr>
<td>Component</td>
<td>Frequency (Hz)</td>
<td>Peak Voltage (V)</td>
</tr>
<tr>
<td>1</td>
<td>0</td>
<td>0.1</td>
</tr>
<tr>
<td>2</td>
<td>50</td>
<td>0.01</td>
</tr>
<tr>
<td>3</td>
<td>100</td>
<td>1</td>
</tr>
</tbody>
</table>
<p><img src="/images/voltagefft/td-example.png" alt="Voltage time domain signal" /></p>
<p>The objective is now to provide a method of illustration that enables quick determination of the frequency components in the summed signal and their respective levels.</p>
<h2 id="the-dft">The DFT</h2>
<p>The DFT or Discrete Fourier Transform converts a discrete time-domain signal into a discrete frequency-domain signal. One notable algorithm for calculating the DFT is the the <a href="https://en.wikipedia.org/wiki/Fast_Fourier_transform">Fast Fourier Transform or FFT</a> which utilises the symmetry of the DFT to optimise performance, and is typically the algorithm implemented by numerical software packages e.g. MATLAB. The DFT algorithm is given by</p>
\[\bar{V}(m) = \sum_{n=0}^{N-1}v(n) \cdot \mathrm{e}^{\frac{-2\pi j}{N} m\cdot n},\quad m=0,\ldots,N-1,\]
<p>where \(\bar{V}\) is the DFT of the discrete time domain signal \(v\), each of length \(N\). Immediately there has been a change of units in attempting to find the frequency domain representation: the DFT calculates the sum over the whole length of the signal as opposed to the instantaneous value. This is equivalent to a change from power to energy. Correction is achieved by normalising by the length of the signals i.e.</p>
\[V = \frac{1}{N} \bar{V},\]
<p>where \(V\) now is the frequency domain representation of the voltage signal. This is a gotcha which got me as the scaling isn’t included in the implementation in most maths software (specifically MATLAB).</p>
<p>Now, finding the magnitude \(\lvert V \rvert\) already provides a physically significant representation, the results are in the same units as the original signal:</p>
<p><img src="/images/voltagefft/fd-notdb.png" alt="Voltage frequency domain without any scaling" /></p>
<p>Inspecting the DFT of the signal sampled at \(F_\mathrm{s} = \)500 Hz, the DC component is correct at 0.1 V, although the 100 Hz component is at half the amplitude it should be. This is because the amplitude is split into the bins between 0 Hz - \(F_\mathrm{s}/2\) and \(F_\mathrm{s}/2\) - \(F_\mathrm{s}\) due to the symmetry of the DFT. It is therefore necessary to scale all of the bins that are not DC by a factor of 2:</p>
\[V(m) = \frac{k(m)}{N} \bar{V(m)},\quad\mathrm{where}\quad
k(m) =
\begin{cases}
2, & m \neq 0\\
1, & m=0
\end{cases}
,\quad m=0,\ldots,N-1.\]
<p>This yields an accurate representation of the signal in the frequency domain. We can do better however as it is difficult to determine the amplitude of the 50 Hz component. This can be solved with…</p>
<h2 id="decibels">Decibels</h2>
<p>Decibels provide a method of scaling data that is over a large range of values such that it can be read easily, and often helps illustrate trends in data that are otherwise unclear. It is useful here as very small voltages often coincide with very large voltages (typically signals vs noise).</p>
<p>A logarithmic scaling similar to converting to decibels can be achieved using</p>
\[10 \cdot \text{log}_{10}(\lvert V \rvert).\]
<p>where the results will now be scaled such that a signal that had a 10 V peak now is at 2 i.e. \(10 \cdot \text{log}_{10}(\lvert 1\times10^2 \rvert) = 2 \), and so a 0.01 V peak is at -2. The exponent in scientific notation is captured in the new value. To present the new data the old values can simply be used as axis labels, and just utilise the new scaling. Most software for plotting encompass a logarithmic plotting option which captures this and displays with the original units, for example with MATLAB and <code class="language-plaintext highlighter-rouge">semilogy()</code>:</p>
<p><img src="/images/voltagefft/fd-db.png" alt="Frequency domain with logarithmic scaling" /></p>
<p>Now the amplitudes are much easier to distinguish over a larger range (the labels help too!).</p>Ben HolmesPlotting a signal in the frequency domain is a fundamental analysis tool which can provide great insight into the signal’s behaviour. Something I have struggled with in the past is getting the units correct such that the amplitude response of the frequency-domain representation has physical significance. In this blog post I aim to outline how to properly find useful units with which to represent voltage signals.Component meters: DE-5000 and M3282018-02-18T00:00:00-08:002018-02-18T00:00:00-08:00https://bencholmes.github.io/posts/2018/02/component-meters<p>Recently I’ve been in need of measuring linear component values to a high degree of accuracy, so decided to purchase a couple of component meters. The first of these is the M328 “transistor tester”, which is a favourite of the DIY community as it is cheap and has all of the plans available on the internet. I put transistor tester in quotes as the meter is designed to measure resistance, capacitance, inductance, transistor type and basic characteristics, and even some parasitic properties. This is quite an impressive boast for a product which I purchased for £6.32!</p>
<p>The only problem with this is that it does not satisfy the need of precision and accuracy. To accomplish this, I purchased a dedicated LCR meter, the DER EE DE-5000. This LCR meter appears to have been designed to rip off the IET Labs DE-5000, and sell at a fraction of the price. A <a href="http://www.eevblog.com/forum/testgear/der-ee-de-5000-unboxing-and-teardown/">teardown at the EEVblog forum</a> shows that the equipment, while being budget, is of decent quality.</p>
<h2 id="quick-specs">Quick specs</h2>
<h3 id="m328">M328</h3>
<ul>
<li>Price: £6.38</li>
<li>Power supply: 9 V battery</li>
<li>Measures:
<ul>
<li>Resistance</li>
<li>Capacitance</li>
<li>Inductance</li>
<li>hFE and Uf of BJTs</li>
<li>Many other factors</li>
</ul>
</li>
<li><a href="/files/Ttester_english.pdf">Manual</a></li>
<li><a href="https://hackaday.com/2015/04/24/review-transistor-tester/">Hackaday Review</a></li>
</ul>
<h3 id="de-5000">DE-5000</h3>
<ul>
<li>Price: £80</li>
<li>Power supply: 9 V battery or external PSU</li>
<li>Measures:
<ul>
<li>Resistance</li>
<li>Capacitance</li>
<li>Inductance</li>
<li>Secondary factors including ESR, dissipation and quality.</li>
</ul>
</li>
<li><a href="/files/DE-5000_manual_english.pdf">Manual</a></li>
<li><a href="https://www.youtube.com/watch?v=sYRxi3BmS_U">Youtube review</a></li>
</ul>
<h2 id="meter-operation">Meter operation</h2>
<p>To illustrate the performance of both meters I have uploaded videos demonstrating how they perform when measuring a 1 MΩ potentiometer.</p>
<h3 id="m328-1">M328</h3>
<video width="400" height="280" controls="">
<source src="/images/MTester.mp4" type="video/mp4" />
Your browser does not support the video tag.
</video>
<p>What is really useful about the M328 is that it has three connections, enabling it to measure the minimum resistance of the potentiometer, here measured to be 0.2 Ω.</p>
<h3 id="de-5000-1">DE-5000</h3>
<video width="320" height="560" controls="">
<source src="/images/DE-5000.mp4" type="video/mp4" />
Your browser does not support the video tag.
</video>
<p>Obviously the dedicated LCR meter that costs over 10x the price offers better precision with the resistance measurement, however the measured values seem pretty close!</p>
<h2 id="gutshots">Gutshots</h2>
<p>I had to disassemble the DE-5000 due to the meter indicating a short at all times. This actually turned out to be a calibration issue that was fixed by simply recalibrating. This did help in two ways however: calibration holds even when powered down so that recalibrating isn’t necessary each use, and I took some shots of the inside of the meter.
<img src="https://i.imgur.com/CrPVbRg.jpg" alt="Component-side DE-5000" />
<img src="https://i.imgur.com/cHPD5DT.jpg" alt="Button/screen-side DE-5000" /></p>Ben HolmesRecently I’ve been in need of measuring linear component values to a high degree of accuracy, so decided to purchase a couple of component meters. The first of these is the M328 “transistor tester”, which is a favourite of the DIY community as it is cheap and has all of the plans available on the internet. I put transistor tester in quotes as the meter is designed to measure resistance, capacitance, inductance, transistor type and basic characteristics, and even some parasitic properties. This is quite an impressive boast for a product which I purchased for £6.32!Modelling logarithmic potentiometer laws2017-11-22T00:00:00-08:002017-11-22T00:00:00-08:00https://bencholmes.github.io/posts/2017/11/logarithmic-potentiometer-laws<p>This post presents a general logarithmic potentiometer law with a curve fit to enable a user to choose a curve that sounds good in their application. The law is computationally expensive as it involves an exponent but is good in terms of flexibility.</p>
<h2 id="background">Background</h2>
<p>Recently I have been looking at circuits with potentiometers. They are everywhere in synthesisers, guitar pedals, etc. and used for controlling aspects of circuit behaviour by changing two resistances between three points.</p>
<p>Potentiometers (pots for short) come in a few flavours: linear, logarithmic, and anti-log. This name defines how the resistance changes with respect to the position of the wiper along the track of the pot. A linear pot means that the primary resistance is proportional to the wiper position, while the secondary resistance is the remaining resistance.</p>
\[R_\mathrm{tot} = R_1 + R_2,\quad R_1 = \alpha R_\mathrm{tot},\quad R_2 = (1-\alpha)R_\mathrm{tot}\]
<p>In this formulation, \(0 \leq \alpha \leq 1 \).</p>
<p>Whereas a linear potentiometer can be seen as straight, the remaining potentiometer laws are curvy. A curved mapping is useful for when controlling things such as volume, where our perception fits closely to a curve. The definition of the exact curve of a potentiometer is difficult to pin down as they differ with manufacturer and also price. For use in simulation, we can define a set of curves that a user can choose from for their needs.</p>
<h2 id="logarithmic-general-form">Logarithmic general form</h2>
<p>The general form of the curve is given by</p>
\[y = a\ b^x + c\]
<p>where \(x\) is the wiper position, \(y\) is the primary resistance, and \(a\), \(b\) and \(c\) are free parameters for curve fitting.</p>
<p>This mapping is applied prior to calculating resistances, so will effectively map \(x\) to \(\alpha\), i.e. \(y=\alpha\). For this reason it can be assumed that the limits of both \(x\) and \(y\) are zero and one. To fit this curve we then have two equations, when both \(x\) and \(y\) are 0:</p>
\[0 = a + c,\quad c = -a\]
<p>And therefore we are given a simpler equation with only two parameters:</p>
\[y = a\ b^x - a\]
<p>Constraining with our second set of points:</p>
\[1 = ab - a,\quad \frac{1}{b-1} = a\]
<p>There is still one equation left to determine the parameter values. I find it useful to map this as a mid-point of the curve, for example saying that when the wiper is at half way I want the resistance to be at 10% of the total. This can be parameterised again so that we can change the midpoint, saying \(x = 0.5\), \(y = y_m\). This gives our final constraint</p>
\[y_m = a(\sqrt{b} - 1),\quad y_m = \frac{\sqrt{b} - 1}{b-1},\quad b = \left(\frac{1}{y_m} - 1\right)^2\]
<h2 id="results">Results</h2>
<p>By setting the value for \(y_m\) we can create a variety of mappings:</p>
<div>
<a href="https://plot.ly/~benholmes/4/?share_key=8cPOlabSsDaHuJ2drdG1CG" target="_blank" title="log-pot" style="display: block; text-align: center;"><img src="https://plot.ly/~benholmes/4.png?share_key=8cPOlabSsDaHuJ2drdG1CG" alt="log-pot" style="max-width: 100%;width: 600px;" width="600" onerror="this.onerror=null;this.src='https://plot.ly/404.png';" /></a>
<script data-plotly="benholmes:4" sharekey-plotly="8cPOlabSsDaHuJ2drdG1CG" src="https://plot.ly/embed.js" async=""></script>
</div>
<p>Note that when setting \(y_m = 0.5\) that \(a = \infty\)! But for this value we can just use a linear map so no need to waste the computation time for the exponent.</p>
<p>Choosing for example \(y_m = 0.15\) will give quite a good approximation of a log pot, though I say this without measurements or further evidence. For an anti-log pot one could select a value around \(0.85\).</p>
<p>If you’re interested in further playing around with this, here is the MATLAB gist (although it should be fairly compatible to Octave, and also self-explanatory if you want to port it):</p>
<script src="https://gist.github.com/bencholmes/87ceeaee702ec0dc1d0426283d2ae2f6.js"></script>Ben HolmesThis post presents a general logarithmic potentiometer law with a curve fit to enable a user to choose a curve that sounds good in their application. The law is computationally expensive as it involves an exponent but is good in terms of flexibility.Mathjax Test2017-11-07T00:00:00-08:002017-11-07T00:00:00-08:00https://bencholmes.github.io/posts/2017/11/mathjax-test<p>This is a test page to see if Mathjax is working. \(\pi\)</p>
\[P(E) = {n \choose k} p^k (1-p)^{ n-k}\]Ben HolmesThis is a test page to see if Mathjax is working. \(\pi\)