diff --git a/README.md b/README.md index 4054d36..867c839 100644 --- a/README.md +++ b/README.md @@ -2867,7 +2867,7 @@ import wave ``` ```python - = wave.open('', 'rb') # Opens the WAV file. + = wave.open('') # Opens the WAV file for reading. = .getframerate() # Returns number of frames per second. = .getnchannels() # Returns number of samples per frame. = .getsampwidth() # Returns number of bytes per sample. @@ -2880,7 +2880,7 @@ import wave .setframerate() # Pass 44100 for CD, 48000 for video. .setnchannels() # Pass 1 for mono, 2 for stereo. .setsampwidth() # Pass 2 for CD, 3 for hi-res sound. -.setparams() # Sets all parameters. +.setparams() # Tuple must contain all parameters. .writeframes() # Appends frames to the file. ``` * **Bytes object contains a sequence of frames, each consisting of one or more samples.** @@ -2904,28 +2904,28 @@ import wave ```python def read_wav_file(filename): def get_int(bytes_obj): - an_int = int.from_bytes(bytes_obj, 'little', signed=(sampwidth != 1)) - return an_int - 128 * (sampwidth == 1) - with wave.open(filename, 'rb') as file: - sampwidth = file.getsampwidth() + an_int = int.from_bytes(bytes_obj, 'little', signed=(p.sampwidth != 1)) + return an_int - 128 * (p.sampwidth == 1) + with wave.open(filename) as file: + p = file.getparams() frames = file.readframes(-1) - bytes_samples = (frames[i : i+sampwidth] for i in range(0, len(frames), sampwidth)) - return [get_int(b) / pow(2, sampwidth * 8 - 1) for b in bytes_samples] + bytes_samples = (frames[i : i + p.sampwidth] for i in range(0, len(frames), p.sampwidth)) + return [get_int(b) / pow(2, p.sampwidth * 8 - 1) for b in bytes_samples], p ``` ### Write Float Samples to WAV File ```python -def write_to_wav_file(filename, float_samples, nchannels=1, sampwidth=2, framerate=44100): +def write_to_wav_file(filename, samples_f, p=None, 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)) + a_float += p.sampwidth == 1 + a_float *= pow(2, p.sampwidth * 8 - 1) + return int(a_float).to_bytes(p.sampwidth, 'little', signed=(p.sampwidth != 1)) + if p is None: + p = wave._wave_params(nchannels, sampwidth, framerate, 0, 'NONE', 'not compressed') with wave.open(filename, 'wb') as file: - file.setnchannels(nchannels) - file.setsampwidth(sampwidth) - file.setframerate(framerate) - file.writeframes(b''.join(get_bytes(f) for f in float_samples)) + file.setparams(p) + file.writeframes(b''.join(get_bytes(f) for f in samples_f)) ``` ### Examples @@ -2936,12 +2936,12 @@ samples_f = (sin(i * 2 * pi * 440 / 44100) for i in range(100_000)) write_to_wav_file('test.wav', samples_f) ``` -#### Adds noise to the mono WAV file: +#### Adds noise to the WAV file: ```python -from random import random -add_noise = lambda value: value + (random() - 0.5) * 0.03 -samples_f = (add_noise(f) for f in read_wav_file('test.wav')) -write_to_wav_file('test.wav', samples_f) +from random import uniform +samples_f, params = read_wav_file('test.wav') +samples_f = (f + uniform(-0.05, 0.05) for f in samples_f) +write_to_wav_file('test.wav', samples_f, params) ``` #### Plays the WAV file: diff --git a/index.html b/index.html index fd1a4f9..408be5b 100644 --- a/index.html +++ b/index.html @@ -54,7 +54,7 @@
- +
@@ -2340,7 +2340,7 @@ imageio.mimsave('test.gif', frames, duration=

#Audio

import wave
 
-
<Wave>  = wave.open('<path>', 'rb')   # Opens the WAV file.
+
<Wave>  = wave.open('<path>')         # Opens the WAV file for reading.
 <int>   = <Wave>.getframerate()       # Returns number of frames per second.
 <int>   = <Wave>.getnchannels()       # Returns number of samples per frame.
 <int>   = <Wave>.getsampwidth()       # Returns number of bytes per sample.
@@ -2351,7 +2351,7 @@ imageio.mimsave('test.gif', frames, duration=# Pass 44100 for CD, 48000 for video.
 <Wave>.setnchannels(<int>)            # Pass 1 for mono, 2 for stereo.
 <Wave>.setsampwidth(<int>)            # Pass 2 for CD, 3 for hi-res sound.
-<Wave>.setparams(<tuple>)             # Sets all parameters.
+<Wave>.setparams(<tuple>)             # Tuple must contain all parameters.
 <Wave>.writeframes(<bytes>)           # Appends frames to the file.
 
    @@ -2372,26 +2372,26 @@ imageio.mimsave('test.gif', frames, duration=

    Read Float Samples from WAV File

    def read_wav_file(filename):
         def get_int(bytes_obj):
    -        an_int = int.from_bytes(bytes_obj, 'little', signed=(sampwidth != 1))
    -        return an_int - 128 * (sampwidth == 1)
    -    with wave.open(filename, 'rb') as file:
    -        sampwidth = file.getsampwidth()
    +        an_int = int.from_bytes(bytes_obj, 'little', signed=(p.sampwidth != 1))
    +        return an_int - 128 * (p.sampwidth == 1)
    +    with wave.open(filename) as file:
    +        p = file.getparams()
             frames = file.readframes(-1)
    -    bytes_samples = (frames[i : i+sampwidth] for i in range(0, len(frames), sampwidth))
    -    return [get_int(b) / pow(2, sampwidth * 8 - 1) for b in bytes_samples]
    +    bytes_samples = (frames[i : i + p.sampwidth] for i in range(0, len(frames), p.sampwidth))
    +    return [get_int(b) / pow(2, p.sampwidth * 8 - 1) for b in bytes_samples], p
     
    -

    Write Float Samples to WAV File

    def write_to_wav_file(filename, float_samples, nchannels=1, sampwidth=2, framerate=44100):
    +

    Write Float Samples to WAV File

    def write_to_wav_file(filename, samples_f, p=None, 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))
    +        a_float += p.sampwidth == 1
    +        a_float *= pow(2, p.sampwidth * 8 - 1)
    +        return int(a_float).to_bytes(p.sampwidth, 'little', signed=(p.sampwidth != 1))
    +    if p is None:
    +        p = wave._wave_params(nchannels, sampwidth, framerate, 0, 'NONE', 'not compressed')
         with wave.open(filename, 'wb') as file:
    -        file.setnchannels(nchannels)
    -        file.setsampwidth(sampwidth)
    -        file.setframerate(framerate)
    -        file.writeframes(b''.join(get_bytes(f) for f in float_samples))
    +        file.setparams(p)
    +        file.writeframes(b''.join(get_bytes(f) for f in samples_f))
     

    Examples

    Saves a 440 Hz sine wave to a mono WAV file:

    from math import pi, sin
    @@ -2400,10 +2400,10 @@ write_to_wav_file('test.wav', samples_f)
     
    -

    Adds noise to the mono WAV file:

    from random import random
    -add_noise = lambda value: value + (random() - 0.5) * 0.03
    -samples_f = (add_noise(f) for f in read_wav_file('test.wav'))
    -write_to_wav_file('test.wav', samples_f)
    +

    Adds noise to the WAV file:

    from random import uniform
    +samples_f, params = read_wav_file('test.wav')
    +samples_f = (f + uniform(-0.05, 0.05) for f in samples_f)
    +write_to_wav_file('test.wav', samples_f, params)
     

    Plays the WAV file:

    # $ pip3 install simpleaudio
    @@ -2931,7 +2931,7 @@ $ deactivate                # Deactivates the active
      
     
       
     
    diff --git a/parse.js b/parse.js
    index af0bb1b..ef23fb1 100755
    --- a/parse.js
    +++ b/parse.js
    @@ -220,7 +220,20 @@ const LOGGING_EXAMPLE =
       '>>> print(open(\'test.log\').read())\n' +
       '2023-02-07 23:21:01,430 CRITICAL:my_module:Running out of disk space.\n';
     
    -const AUDIO =
    +const AUDIO_1 =
    +  'def write_to_wav_file(filename, samples_f, p=None, nchannels=1, sampwidth=2, framerate=44100):\n' +
    +  '    def get_bytes(a_float):\n' +
    +  '        a_float = max(-1, min(1 - 2e-16, a_float))\n' +
    +  '        a_float += p.sampwidth == 1\n' +
    +  '        a_float *= pow(2, p.sampwidth * 8 - 1)\n' +
    +  '        return int(a_float).to_bytes(p.sampwidth, \'little\', signed=(p.sampwidth != 1))\n' +
    +  '    if p is None:\n' +
    +  '        p = wave._wave_params(nchannels, sampwidth, framerate, 0, \'NONE\', \'not compressed\')\n' +
    +  '    with wave.open(filename, \'wb\') as file:\n' +
    +  '        file.setparams(p)\n' +
    +  '        file.writeframes(b\'\'.join(get_bytes(f) for f in samples_f))\n';
    +
    +const AUDIO_2 =
       'from math import pi, sin\n' +
       'samples_f = (sin(i * 2 * pi * 440 / 44100) for i in range(100_000))\n' +
       'write_to_wav_file(\'test.wav\', samples_f)\n';
    @@ -839,7 +852,8 @@ function fixHighlights() {
       $(`code:contains(import curses, os)`).html(CURSES);
       $(`code:contains(pip3 install tqdm)`).html(PROGRESS_BAR);
       $(`code:contains(>>> log.basicConfig()`).html(LOGGING_EXAMPLE);
    -  $(`code:contains(samples_f = (sin(i *)`).html(AUDIO);
    +  $(`code:contains(a_float = max()`).html(AUDIO_1);
    +  $(`code:contains(samples_f = (sin(i *)`).html(AUDIO_2);
       $(`code:contains(collections, dataclasses, enum, io, itertools)`).html(MARIO);
       $(`code:contains(>>> gb = df.groupby)`).html(GROUPBY);
       $(`code:contains(cdef   = )`).html(CYTHON_1);