Reading 24-Bit WAV with wavio Python 3.5
<p>I am using <a href="https://github.com/WarrenWeckesser/wavio/blob/master/wavio.py" rel="nofollow">wavio</a> by WarrenWeckesser as I need to read 24-bit wav files in python. The wav files I have are produced by some instrumentation and I am trying to get the raw values without any normalisation or scaling.</p>

<p>In the wavio module the code that does the work is this:</p>

<pre><code>    if sampwidth == 3:
        a = _np.empty((num_samples, nchannels, 4), dtype=_np.uint8)
        raw_bytes = _np.fromstring(data, dtype=_np.uint8)
        a[:, :, :sampwidth] = raw_bytes.reshape(-1, nchannels, sampwidth)
        a[:, :, sampwidth:] = (a[:, :, sampwidth - 1:sampwidth] &gt;&gt; 7) * 255
        result = a.view('&lt;i4').reshape(a.shape[:-1]
</code></pre>

<p>Can someone explain what it is actually doing (I am a relatively new to numpy and array slicing). I understand most of it but I don't understand what is going on here:</p>

<pre><code>    a[:, :, sampwidth:] = (a[:, :, sampwidth - 1:sampwidth] &gt;&gt; 7) * 255
</code></pre>

<p>In my case it does the transform from 24 to 32 bit but I can't work out whether it is scaling the data, or simply padding it out without changing any raw values.</p>

<p>The shape of <code>a</code> is <code>(num_samples, nchannels, 4)</code> and <code>sampwidth == 3</code>, so that line is the same as</p>

<pre><code>a[:, :, 3:] = (a[:, :, 2:3] &gt;&gt; 7) * 255
</code></pre>

<p>which is the same as</p>

<pre><code>a[:, :, 3] = (a[:, :, 2] &gt;&gt; 7) * 255
</code></pre>

<p>we could devectorize the outer two loops:</p>

<pre><code>for i in range(num_samples):
    for j in range(nchannels):
        a[i, j, 3] = (a[i, j, 2] &gt;&gt; 7) * 255
</code></pre>

<p>The dtype of <code>a</code> is <code>_np.uint8</code>, so <code>a[...] &gt;&gt; 7</code> can only give out 0 when the value is &lt;128, or 1 when it is â¥128, so the above becomes:</p>

<pre><code>for i in range(num_samples):
    for j in range(nchannels):
        v = a[i, j, 2]
        a[i, j, 3] = 255 if v &gt;= 128 else 0
</code></pre>

<p>If the data are 24-bit little-endian integers, this is equivalent to doing a <a href="https://en.wikipedia.org/wiki/Sign_extension" rel="nofollow">sign-extension</a> into 32-bit.</p>

python numpy wav