Flush to zero and/or significant digits in python floats
<p>I'm trying to conduct an ICA application using audio files (.wavs). When using scipy wavfile, I have noticed from using cprofile, that my load_wav function performs very poorly. It takes 30 minutes to process a 44100 stereo .wav file at a CPU speed of 4.5 Ghz. Bear in mind, the .wav file is only 10 seconds in duration. Here is my function for reference:</p>

<pre><code>def load_wav(filename,samplerate=44100):

    # load file
    rate, data = wavfile.read(filename)

    # convert stereo to mono
    if len(data.shape) &gt; 1:
        data = data[:,0]/2 + data[:,1]/2

    # re-interpolate samplerate    
    ratio = float(samplerate) / float(rate)
    data = resample(data, len(data) * ratio)

    return samplerate, data.astype(np.int16)
</code></pre>

<p>it's primarily the re-interpolate section that takes forever. I researched what I could on it, and it seems that not all computers are adept at dealing with numerous floats. Some floats may be close to zero but not quite. In my audio example, this could be the result of pauses in a person's speech, or could happen at the beginning or end of a file, and the list goes on. </p>

<p>So to get down to it, can someone share something like this c++ workaround in Python? They call this issue "denormals" and they suggest flush to zero.</p>

<p><a href="http://blog.audio-tk.com/2016/09/20/audio-toolkit-handling-denormals/?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+eifelle%2FCPPV+%28Matt%27s+blog%29" rel="nofollow">http://blog.audio-tk.com/2016/09/20/audio-toolkit-handling-denormals/?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+eifelle%2FCPPV+%28Matt%27s+blog%29</a></p>

<p>And it would also be peace of mind to know whether or not zero is the only number to be wary of. Maybe, I should set significant digits for all numbers? Would that make a difference in audio applications? If so, how would that look in Python? Obviously we may want to avoid going overboard, like using integers only, which would probably result in a lot of sound degradation.</p>

<p>Anyway, I think you get the idea of my question, I want the computation speed to be within reason, but still be able to have a half decent numpy representation of the .wav.</p>

<p>Please help out if you can,</p>

<p>Thank you</p>

<p>
Imports are as follows:</p>

<pre><code>import numpy as np
from scipy.io import wavfile
from scipy.signal import resample
</code></pre>

<p>also if you want to view the jupyter notebook to see the ICA application in its entirety, you can do so here:
<a href="http://web.archive.org/web/20150314223948/http://shogun-toolbox.org/static/notebook/current/bss_audio.html" rel="nofollow">http://web.archive.org/web/20150314223948/http://shogun-toolbox.org/static/notebook/current/bss_audio.html</a></p>

<p>**the link uses Python 2.7, I'm using Python 3.5, so things may vary slightly.</p>

<p>--Edit</p>

<p>Well. sorry for the confusion. The answer to why the shape of X changed is due to the fact the example notebook took the dot product differently than the way I was used to. They used <code>S=(np.c_[s1,s2,s3]).T</code>  then <code>np.dot(A,S)</code>. I usually use <code>S=np.c_[s1,s2,s3]</code> then <code>np.dot(S,A.T)</code>. So all I had to do was transform a few things to get the desired shape of X. Classic case of not looking before I leaped. I was wrong to have blamed <code>np.delete(data,-1)</code> for causing that shape mishap. It has proven to work for handling primes, guaranteeing data will be an even number. I will delete some of my unnecessary comments to restore clarity to my post.</p>

<p>The verdict is still out on flush to zero / significant digit thresholds in terms of audio processing code efficiency. I hope this particular aspect of my question is revisited sometime soon. Until then, I will be using <code>np.delete(data,-1)</code> as a quick and dirty solution when dealing with large/prime numbers.</p>

<p>As AndyG already commented, <a href="http://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.resample.html#scipy.signal.resample" rel="nofollow">the documentation for <code>scipy.signal.resample</code></a> warns you that</p>

<blockquote>
  <p>... resample uses FFT transformations, which can be very slow if the number of input samples is large and prime, see <code>scipy.fftpack.fft</code>.</p>
</blockquote>

<p>441263 is both large and prime.</p>

<p>If you have a version of scipy >= 0.18.0 you could try <a href="http://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.resample_poly.html#scipy.signal.resample_poly" rel="nofollow"><code>resample_poly</code></a> instead:</p>

<blockquote>
  <p>This polyphase method will likely be faster than the Fourier method in scipy.signal.resample when the number of samples is large and prime, or when the number of samples is large and up and down share a large greatest common denominator.</p>
</blockquote>

<p>For example:</p>

<pre><code>import numpy
from scipy.signal import resample, resample_poly

x = np.random.randn(441263)

%timeit resample(x, x.shape[0] // 4)
# 1 loop, best of 3: 2min 18s per loop

%timeit resample_poly(x, 10, 40)
# 100 loops, best of 3: 9.05 ms per loop
</code></pre>

python c++ audio scipy signal-processing