How to manipulate wav file data in Python?

后端 未结 1 723
天命终不由人
天命终不由人 2021-01-04 23:23

I\'m trying to read a wav file, then manipulate its contents, sample by sample

Here\'s what I have so far:

import scipy.io.wavfile
import math

rate,         


        
相关标签:
1条回答
  • 2021-01-04 23:38

    The array data returned by wavfile.read is a numpy array with an integer data type. The data type of a numpy array can not be changed in place, so this line:

    data[i][0] = math.sin(data[i][0])
    

    casts the result of math.sin to an integer, which will always be 0.

    Instead of that line, create a new floating point array to store your computed result.

    Or use numpy.sin to compute the sine of all the elements in the array at once:

    import numpy as np
    import scipy.io.wavfile
    
    rate, data = scipy.io.wavfile.read('xenencounter_23.wav')
    
    sin_data = np.sin(data)
    
    print sin_data
    

    From your additional comments, it appears that you want to take the sine of each value and write out the result as a new wav file.

    Here is an example that (I think) does what you want. I'll use the file 'M1F1-int16-AFsp.wav' from here: http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Samples.html. The function show_info is just a convenient way to illustrate the results of each step. If you are using an interactive shell, you can use it to inspect the variables and their attributes.

    import numpy as np
    from scipy.io import wavfile
    
    def show_info(aname, a):
        print "Array", aname
        print "shape:", a.shape
        print "dtype:", a.dtype
        print "min, max:", a.min(), a.max()
        print
    
    rate, data = wavfile.read('M1F1-int16-AFsp.wav')
    
    show_info("data", data)
    
    # Take the sine of each element in `data`.
    # The np.sin function is "vectorized", so there is no need
    # for a Python loop here.
    sindata = np.sin(data)
    
    show_info("sindata", sindata)
    
    # Scale up the values to 16 bit integer range and round
    # the value.
    scaled = np.round(32767*sindata)
    
    show_info("scaled", scaled)
    
    # Cast `scaled` to an array with a 16 bit signed integer data type.
    newdata = scaled.astype(np.int16)
    
    show_info("newdata", newdata)
    
    # Write the data to 'newname.wav'
    wavfile.write('newname.wav', rate, newdata)
    

    Here's the output. (The initial warning means there is perhaps some metadata in the file that is not understood by scipy.io.wavfile.read.)

    <snip>/scipy/io/wavfile.py:147: WavFileWarning: Chunk (non-data) not understood, skipping it.
      WavFileWarning)
    Array 'data'
    shape: (23493, 2)
    dtype: int16
    min, max: -7125 14325
    
    Array 'sindata'
    shape: (23493, 2)
    dtype: float32
    min, max: -0.999992 0.999991
    
    Array 'scaled'
    shape: (23493, 2)
    dtype: float32
    min, max: -32767.0 32767.0
    
    Array 'newdata'
    shape: (23493, 2)
    dtype: int16
    min, max: -32767 32767
    

    The new file 'newname.wav' contains two channels of signed 16 bit values.

    0 讨论(0)
提交回复
热议问题