Browse Source

Audio

pull/42/head
Jure Šorn 5 years ago
parent
commit
1b35555207
2 changed files with 46 additions and 29 deletions
  1. 39
      README.md
  2. 36
      index.html

39
README.md

@ -2662,23 +2662,32 @@ import wave, struct
<Wave_write>.setframerate(<int>) # Frames per second.
```
### Read Frames from WAV File
### Read Float Frames from WAV File
```python
def read_wav_file(filename):
def get_int(a_bytes):
an_int = int.from_bytes(a_bytes, 'little', signed=width!=1)
return an_int - 128 * (width == 1)
with wave.open(filename, 'rb') as file:
frames = file.readframes(file.getnframes())
return [a[0] for a in struct.iter_unpack('<h', frames)]
width = file.getsampwidth()
chunks = (frames[i: i + width] for i in range(0, len(frames), width))
return [get_int(a) / pow(2, width * 8 - 1) for a in chunks]
```
### Write Frames to WAV File
### Write Float Frames to WAV File
```python
def write_to_wav_file(filename, frames_int, mono=True):
frames_short = (struct.pack('<h', a) for a in frames_int)
def write_to_wav_file(filename, frames_float, nchannels=1, sampwidth=2, framerate=44100):
def get_bytes(a_float):
a_float = max(-1, min(1 - 2e-16, a_float))
a_float += sampwidth == 1
a_float *= pow(2, sampwidth * 8 - 1)
return int(a_float).to_bytes(sampwidth, 'little', signed=sampwidth!=1)
with wave.open(filename, 'wb') as file:
file.setnchannels(1 if mono else 2)
file.setsampwidth(2)
file.setframerate(44100)
file.writeframes(b''.join(frames_short))
file.setnchannels(nchannels)
file.setsampwidth(sampwidth)
file.setframerate(framerate)
file.writeframes(b''.join(get_bytes(a) for a in frames_float))
```
### Examples
@ -2686,18 +2695,18 @@ def write_to_wav_file(filename, frames_int, mono=True):
```python
from math import pi, sin
frames_f = (sin(i * 2 * pi * 440 / 44100) for i in range(100000))
frames_i = (int(a * 30000) for a in frames_f)
write_to_wav_file('test.wav', frames_i)
write_to_wav_file('test.wav', frames_f)
```
#### Adds noise to a mono WAV file:
```python
from random import randint
add_noise = lambda value: max(-32768, min(32767, value + randint(-500, 500)))
frames_i = (add_noise(a) for a in read_wav_file('test.wav'))
write_to_wav_file('test.wav', frames_i)
from random import random
add_noise = lambda value: max(-1, min(1, value + (random()-0.5)*0.03))
frames_f = (add_noise(a) for a in read_wav_file('test.wav'))
write_to_wav_file('test.wav', frames_f)
```
Synthesizer
-----------
#### Plays Popcorn by Gershon Kingsley:

36
index.html

@ -2262,32 +2262,40 @@ imageio.mimsave(<span class="hljs-string">'test.gif'</span>, frames, duration=<s
&lt;Wave_write&gt;.setsampwidth(&lt;int&gt;) <span class="hljs-comment"># Sample size in bytes.</span>
&lt;Wave_write&gt;.setframerate(&lt;int&gt;) <span class="hljs-comment"># Frames per second.</span>
</code></pre>
<div><h3 id="readframesfromwavfile">Read Frames from WAV File</h3><pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">read_wav_file</span><span class="hljs-params">(filename)</span>:</span>
<div><h3 id="readfloatframesfromwavfile">Read Float Frames from WAV File</h3><pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">read_wav_file</span><span class="hljs-params">(filename)</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_int</span><span class="hljs-params">(a_bytes)</span>:</span>
an_int = int.from_bytes(a_bytes, <span class="hljs-string">'little'</span>, signed=width!=<span class="hljs-number">1</span>)
<span class="hljs-keyword">return</span> an_int - <span class="hljs-number">128</span> * (width == <span class="hljs-number">1</span>)
<span class="hljs-keyword">with</span> wave.open(filename, <span class="hljs-string">'rb'</span>) <span class="hljs-keyword">as</span> file:
frames = file.readframes(file.getnframes())
<span class="hljs-keyword">return</span> [a[<span class="hljs-number">0</span>] <span class="hljs-keyword">for</span> a <span class="hljs-keyword">in</span> struct.iter_unpack(<span class="hljs-string">'&lt;h'</span>, frames)]
width = file.getsampwidth()
chunks = (frames[i: i + width] <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">0</span>, len(frames), width))
<span class="hljs-keyword">return</span> [get_int(a) / pow(<span class="hljs-number">2</span>, width * <span class="hljs-number">8</span> - <span class="hljs-number">1</span>) <span class="hljs-keyword">for</span> a <span class="hljs-keyword">in</span> chunks]
</code></pre></div>
<div><h3 id="writeframestowavfile">Write Frames to WAV File</h3><pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">write_to_wav_file</span><span class="hljs-params">(filename, frames_int, mono=True)</span>:</span>
frames_short = (struct.pack(<span class="hljs-string">'&lt;h'</span>, a) <span class="hljs-keyword">for</span> a <span class="hljs-keyword">in</span> frames_int)
<div><h3 id="writefloatframestowavfile">Write Float Frames to WAV File</h3><pre><code class="python language-python hljs"><span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">write_to_wav_file</span><span class="hljs-params">(filename, frames_float, nchannels=<span class="hljs-number">1</span>, sampwidth=<span class="hljs-number">2</span>, framerate=<span class="hljs-number">44100</span>)</span>:</span>
<span class="hljs-function"><span class="hljs-keyword">def</span> <span class="hljs-title">get_bytes</span><span class="hljs-params">(a_float)</span>:</span>
a_float = max(<span class="hljs-number">-1</span>, min(<span class="hljs-number">1</span> - <span class="hljs-number">2e-16</span>, a_float))
a_float += sampwidth == <span class="hljs-number">1</span>
a_float *= pow(<span class="hljs-number">2</span>, sampwidth * <span class="hljs-number">8</span> - <span class="hljs-number">1</span>)
<span class="hljs-keyword">return</span> int(a_float).to_bytes(sampwidth, <span class="hljs-string">'little'</span>, signed=sampwidth!=<span class="hljs-number">1</span>)
<span class="hljs-keyword">with</span> wave.open(filename, <span class="hljs-string">'wb'</span>) <span class="hljs-keyword">as</span> file:
file.setnchannels(<span class="hljs-number">1</span> <span class="hljs-keyword">if</span> mono <span class="hljs-keyword">else</span> <span class="hljs-number">2</span>)
file.setsampwidth(<span class="hljs-number">2</span>)
file.setframerate(<span class="hljs-number">44100</span>)
file.writeframes(<span class="hljs-string">b''</span>.join(frames_short))
file.setnchannels(nchannels)
file.setsampwidth(sampwidth)
file.setframerate(framerate)
file.writeframes(<span class="hljs-string">b''</span>.join(get_bytes(a) <span class="hljs-keyword">for</span> a <span class="hljs-keyword">in</span> frames_float))
</code></pre></div>
<div><h3 id="examples-1">Examples</h3><div><h4 id="savesasinewavetoamonowavfile">Saves a sine wave to a mono WAV file:</h4><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> math <span class="hljs-keyword">import</span> pi, sin
frames_f = (sin(i * <span class="hljs-number">2</span> * pi * <span class="hljs-number">440</span> / <span class="hljs-number">44100</span>) <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> range(<span class="hljs-number">100000</span>))
frames_i = (int(a * <span class="hljs-number">30000</span>) <span class="hljs-keyword">for</span> a <span class="hljs-keyword">in</span> frames_f)
write_to_wav_file(<span class="hljs-string">'test.wav'</span>, frames_i)
write_to_wav_file(<span class="hljs-string">'test.wav'</span>, frames_f)
</code></pre></div></div>
<div><h4 id="addsnoisetoamonowavfile">Adds noise to a mono WAV file:</h4><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> random <span class="hljs-keyword">import</span> randint
add_noise = <span class="hljs-keyword">lambda</span> value: max(<span class="hljs-number">-32768</span>, min(<span class="hljs-number">32767</span>, value + randint(<span class="hljs-number">-500</span>, <span class="hljs-number">500</span>)))
frames_i = (add_noise(a) <span class="hljs-keyword">for</span> a <span class="hljs-keyword">in</span> read_wav_file(<span class="hljs-string">'test.wav'</span>))
write_to_wav_file(<span class="hljs-string">'test.wav'</span>, frames_i)
<div><h4 id="addsnoisetoamonowavfile">Adds noise to a mono WAV file:</h4><pre><code class="python language-python hljs"><span class="hljs-keyword">from</span> random <span class="hljs-keyword">import</span> random
add_noise = <span class="hljs-keyword">lambda</span> value: max(<span class="hljs-number">-1</span>, min(<span class="hljs-number">1</span>, value + (random()<span class="hljs-number">-0.5</span>)*<span class="hljs-number">0.03</span>))
frames_f = (add_noise(a) <span class="hljs-keyword">for</span> a <span class="hljs-keyword">in</span> read_wav_file(<span class="hljs-string">'test.wav'</span>))
write_to_wav_file(<span class="hljs-string">'test.wav'</span>, frames_f)
</code></pre></div>
<div><h2 id="synthesizer"><a href="#synthesizer" name="synthesizer">#</a>Synthesizer</h2><div><h4 id="playspopcornbygershonkingsley">Plays Popcorn by Gershon Kingsley:</h4><pre><code class="python language-python hljs"><span class="hljs-comment"># $ pip3 install simpleaudio</span>

Loading…
Cancel
Save