How do I produce a sound signal from an array?
<p>I'm working on a project which requires some sound processing. I know how to record the sound and convert the signal into a float in order to process it. The problem is, that I don't know how to convert those numbers back to bytes in order to play the final processed sound.</p>

<p>Imagine an array like this one:</p>

<pre><code>[-954.04373976038096, -289.02199657142637, 603.07726299005469, 558.24833180011706, -252.49007227640698, -884.07367717525278, -754.89044791362232]
</code></pre>

<p>And I need to convert it to something similar to this, in order to play the sound:</p>

<pre><code>[b'\x92\xffQ\xffO\xff\xad\xff\x12\x00\xfc\xfff\xff\xe4\xfe\xee\xfeC\xffA']
</code></pre>

<p>If I convert each number to bytes using <code>bytes()</code> and play, it I just get noise. When I convert it back to a float in order to see what's happening, it has a different value than the original float.</p>

<p>First, you'll need to know the maximum range of your values. Given your values, that might be from <code>-2000.0</code> to <code>2000.0</code>, but I have no idea, so my guess is most likely wrong. Typically, the numbers in a floating point audio signal range from <code>-1.0</code> to <code>1.0</code>. Obviously, you have much larger values. If you have a reason for that, it's OK, but if not, you should probably scale your signals to the range from <code>-1.0</code> to <code>1.0</code>. Many applications and libraries use this convention.</p>

<p>Then, you'll need to know the proper target format. There is no way to know that from your question. For example, your target format might be signed 16-bit integers in "little endian" byte order.</p>

<p>To convert the values, you'll first have to divide all input values by the maximum possible (absolute) value. If your data ranges from <code>-1.0</code> to <code>1.0</code>, this is a no-op. Then, multiply those values with the maximum number of your target format. If your target format is 16-bit integers, that's <code>2**15</code>, or <code>32768</code>. Actually, the largest signed 16-bit integer is one less (because <code>0</code> needs to be stored, too), namely <code>32767</code>, so you should probably use this value to avoid overflow. The resulting values are already correct, but they are still floating point values. So you should convert them to <code>int</code>. Finally, you can convert those integer values to <code>bytes</code>, e.g. using the <code>struct</code> module. There you'll have to make sure to specify the correct <a href="https://docs.python.org/3/library/struct.html#format-strings" rel="nofollow">format string</a>, e.g. <code>'&lt;h'</code> for little-endian signed 16-bit numbers.</p>

<p>Having said all that, it's probably much easier to use a sound I/O library that does the necessary conversions for you, e.g. the <a href="http://python-sounddevice.readthedocs.io/" rel="nofollow">sounddevice</a> module. You'll still need to scale your floating point values to the range from <code>-1.0</code> to <code>1.0</code>, but the rest can be done automatically. If you are using NumPy arrays it's even simpler, but it also works with plain Python buffers.</p>

python audio byte