python使用wave和matplotlib生成和绘制wav文件

#!/usr/bin/env python3
import numpy as np
from scipy.io import wavfile
import numpy as np
import matplotlib.pyplot as plt
import wave
import os

#frame_rate:采样率  frequency:频率 length:文件时长秒
def generate_sin_wave(filepath:str, frame_rate:int, freq:int, length:int):
    
    #生成正弦
    t_points = np.linspace(0, length, frame_rate * length)  #start, stop, number
    amplitude_points = np.sin(freq * 2 * np.pi * t_points)  #  
    
    #处理数据,从[-1,1]转化为[-2**15-1, 2**15-1] 
    max_of_amplitude = np.max(np.abs(amplitude_points))
    maxint16 = np.iinfo(np.int16).max  # == 2**15-1
 
    print('max_of_amplitude:%f, maxint16:%f' %(max_of_amplitude, maxint16))
     
    # 转换
    amplitude_points =  amplitude_points * maxint16 / max_of_amplitude

    #将数组的数据类型转换为指定的类型:int16
    amplitude_points = amplitude_points.astype(np.int16) 

    #写入文件
    wavfile.write(filepath, frame_rate, amplitude_points)

    print("generate sin wave file successfully, written to:" + filepath )

#maxshow这个值怎么设都不会有问题
def visualize_wave(filepath: str, maxshow:int, spectrum:bool): 
    
    # 设置figure大小  像素
    plt.figure(figsize = (12, 8), dpi = 100)
        
    # reading the audio file 
    wavefile = wave.open(filepath) 
    params = wavefile.getparams()

    nchannels, sample_width, frame_rate, nframes = params[:4]
    
    print('nchannels:%d, sample_width:%d, sample_rate:%d, nframes:%d'
          % (nchannels, sample_width, frame_rate, nframes))
    
    # reads all the frames  
    # -1 indicates all or max frames 
    signal = wavefile.readframes(-1) 
    signal = np.frombuffer(signal, dtype = np.int16) 
      
    # gets the frame rate 
    frame_rate = wavefile.getframerate() 
  
    # to Plot the x-axis in seconds  
    # you need get the frame rate  
    # and divide by size of your signal 
    # to create a Time Vector  
    # spaced linearly with the size  
    # of the audio file 
    time = np.linspace( 
        0, # start 
        len(signal) / frame_rate, 
        num = len(signal) 
    ) 
      
    # title of the plot 
    plt.title("Sound Wave") 
      
    # label of x-axis 
    plt.xlabel("Time") 
    
    # label of y-axis 
    plt.xlabel("Amplitude") 
    
    #切片,太多了显示不了,显示最初的2000个采样
    points = len(time)
    if points > maxshow :
        time = time[0:maxshow:1]
        signal = signal[0:maxshow:1]
    
    # actual plotting 
    if spectrum:
        plt.specgram(signal, Fs=sample_rate, vmin=-20, vmax=50)
        plt.colorbar()
    else:
        plt.plot(time, signal) 
    
    
    # shows the plot  
    # in new window 
    plt.show() 
  
    # you can also save 
    # the plot using 
    # plt.savefig('filename')
    
if __name__ == "__main__": 
    
    rootpath = "./generated"
    if not os.path.exists(rootpath):
        os.mkdir(rootpath, mode=755)
    
    filepath = rootpath + "/sine.wav"
    generate_sin_wave(filepath, 16000, 600, 10)
    visualize_wave(filepath, 1000, False)
    
    
    sample_filepath = rootpath + "/file_example_WAV_1MG.wav" #
    if os.path.exists(sample_filepath):
        visualize_wave(sample_filepath, 30000, False)
    
    

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值