国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Python 從零開始制作自己的聲音 - wave模塊讀寫wav文件詳解

這篇具有很好參考價值的文章主要介紹了Python 從零開始制作自己的聲音 - wave模塊讀寫wav文件詳解。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

計算機(jī)經(jīng)常被用于處理音頻這種真實世界中的數(shù)據(jù)。聲音經(jīng)過采樣,量化和編碼后,存儲在音頻文件,如wav文件中。
文章首先介紹wave模塊的基礎(chǔ)用法; 再通過生成一定頻率聲波的算法實現(xiàn),來深入講解wave庫的使用。

wave模塊

wave模塊提供了一個處理 wav 聲音格式的便利接口, 可獲取wav文件頭信息, 從文件讀取數(shù)據(jù), 也可直接將bytes格式的數(shù)據(jù)寫入wav文件。

wave.open()

wave.open(file, mode=None)
類似于普通的打開文件,函數(shù)接收兩個參數(shù),file為文件名或文件對象,mode可取"r",“rb”,“w”,“wb"四個值,其中"r"和"rb”, "w"和"wb"效果完全相同。如下:

>>> wave.open('音樂.wav','r')
<wave.Wave_read object at 0x0355E810>
>>> wave.open('test.wav','w')
<wave.Wave_write object at 0x0355E810>

以讀模式打開的文件會返回Wave_read 對象, 寫模式打開時會返回Wave_write 對象。

Wave_read

Wave_read 對象通過wave.open() 函數(shù)創(chuàng)建。wave文件記錄了二進(jìn)制的音頻數(shù)據(jù),由許多幀組成,一個采樣對應(yīng)一個幀,每一幀長度為1或2字節(jié)。

Wave_read.getnchannels():返回聲道數(shù)量(1 為單聲道,2 為立體聲)

Wave_read.getsampwidth():返回采樣字節(jié)長度 (每一幀的字節(jié)長度)。

Wave_read.getframerate():返回采樣頻率。

Wave_read.getnframes():返回音頻總幀數(shù)。

Wave_read.getcomptype()Wave_read.getcompname():返回壓縮類型。

Wave_read.readframes(n)
讀取并返回以 bytes 對象表示的最多 n 幀音頻。

Wave_read.tell()
返回當(dāng)前文件指針位置。

Wave_read.setpos(pos)
設(shè)置文件指針到指定位置。

Wave_write

Wave_write 對象也通過wave.open() 函數(shù)創(chuàng)建。

Wave_write.setnchannels(n):設(shè)置聲道數(shù)。

Wave_write.setsampwidth(n):設(shè)置采樣字節(jié)長度為 n。

Wave_write.setframerate(n):設(shè)置采樣頻率為 n。

Wave_write.setnframes(n):設(shè)置總幀數(shù)為 n。(后來發(fā)現(xiàn)調(diào)用writeframes()時,wave模塊會自動更新總幀數(shù),實際上不需要調(diào)用這個函數(shù))

Wave_write.setcomptype(type, name):設(shè)置壓縮格式。(目前只支持 NONE 即無壓縮格式。)

Wave_write.tell()
返回當(dāng)前文件指針,其指針含義和 Wave_read.tell() 以及 Wave_read.setpos() 是一致的。

Wave_write.writeframes(data)(或writeframesraw(data)
寫入bytes格式的音頻幀,并更新 nframes。

Wave_write.close()
確保 nframes 是正確的,并在文件被 wave 打開時關(guān)閉它。 此方法會在對象收集時被調(diào)用。 如果輸出流不可查找且 nframes 與實際寫入的幀數(shù)不匹配時引發(fā)異常。

初步: 拼接音頻

程序先將兩段音頻中的數(shù)據(jù)讀入data1data2中,再將讀取的數(shù)據(jù)拼接,寫入result.wav。注意兩段音頻的采樣頻率、采樣字節(jié)長度需要一致。

import wave

sampwidth = 1
framerate = 22050

with wave.open('音樂1.wav','rb') as f1:
    sampwidth = f1.getsampwidth()
    framerate = f1.getframerate()
    nframes1=f1.getnframes()
    data1=f1.readframes(nframes1)

with wave.open('音樂2.wav','rb') as f2:
    nframes2=f2.getnframes()
    data2=f2.readframes(nframes2)

with wave.open('result.wav','wb') as fw:
    fw.setnchannels(1)
    fw.setsampwidth(sampwidth)
    fw.setframerate(framerate)
    #fw.setnframes(nframes1+nframes2)
    fw.writeframesraw(data1)
    fw.writeframesraw(data2)

初次實現(xiàn)

現(xiàn)在開始制作自己的聲音。程序生成一段頻率為200Hz, 長度為1.8秒的蜂鳴聲。

import wave
from winsound import PlaySound,SND_FILENAME

file = 'test.wav'
len_= 1.8 # 秒
frequency = 200
sampwidth = 1 #每一幀寬度(采樣字節(jié)長度)
framerate = 22050 # 采樣頻率 (越大音質(zhì)越好)
length = int(framerate * len_ * sampwidth)
para = [0b00000000]*(framerate//frequency//2*sampwidth)\
       +[0b11111111]*(framerate//frequency//2*sampwidth) # 音頻的一小段
data=bytes(para)

# 生成wav文件
with wave.open(file,'wb') as f:
    f.setnchannels(1)
    f.setsampwidth(sampwidth)
    f.setframerate(framerate)
    # f.setnframes(length) (可選)
    f.writeframes(data * (length // len(data)))

PlaySound(file,SND_FILENAME) # 播放生成的wav

再次實現(xiàn)

上述程序生成的是方波,并有一些缺陷,如para0b00000000b11111111的長度是整數(shù)且相同,導(dǎo)致生成的聲音頻率不精確,等等。
這里合成一段200Hz,長度為1.8秒的正弦波。

import wave,math
from winsound import PlaySound,SND_FILENAME

def generate(T,total,volume,sine=False):
    # T: 周期, total 總長度, 都以幀為單位
    if not sine:
        h = T / 2
        for i in range(total):
            if i % T >= h:
                yield volume
            else:
                yield 0
    else:
        # 計算方法: sin 的 T = 2*pi / w
        w = 2 * math.pi  / T; r = volume / 2
        for i in range(total):
            yield int(math.sin(w * i) * r + r)

file = 'test.wav'
len_= 1.8 # 秒
frequency = 200
sampwidth = 1
framerate = 22050
sine=True
volume = 255 # 音量, 0 - 255
data = bytes(generate(framerate / frequency, int(framerate*len_),
                              volume,sine)) # bytes能接收0-255整數(shù)型的迭代器

with wave.open(file,'wb') as f:
    f.setnchannels(1)
    f.setsampwidth(sampwidth)
    f.setframerate(framerate)
    f.writeframes(data)

PlaySound(file,SND_FILENAME)

運行程序會發(fā)現(xiàn),正弦波聽起來比方波更加柔和。
自己做的合成與Python內(nèi)置的音頻合成對比:

import winsound
# Beep(freq,duration),參數(shù)分別是頻率和毫秒為單位的持續(xù)時間
winsound.Beep(200,1800)

發(fā)現(xiàn), 前述程序很好地仿真了調(diào)用內(nèi)置的Beep函數(shù)發(fā)聲。
但音質(zhì)有區(qū)別, 這是采樣字節(jié)長度為1(只有8位)導(dǎo)致的, 還需要加大采樣字節(jié)長度。
最終的程序如下:

import wave,math,struct
from winsound import PlaySound,SND_FILENAME
def generate(T,total,volume,sampwidth,sine=False):
    # T: 周期, total 總長度, 以幀為單位
    volume = min(volume * 2**(sampwidth*8),2**(sampwidth*8) - 1)
    if not sine:
        h = T / 2
        for i in range(total):
            if i % T >= h:
                yield volume
            else:
                yield 0
    else:
        w = 2 * math.pi  / T; r = volume / 2
        for i in range(total):
            # T = 2*pi / w
            yield int(math.sin(w * i) * r + r)

file = 'test.wav'
len_= 1.8 # 秒
frequency = 200
sampwidth = 2
framerate = 22050
sine=True
volume = 255
# 8位的wav文件的一幀是無符號8位整數(shù), 而16位的一幀是有符號的整數(shù)(-32768至32767)。
if sampwidth == 1: # 8位
    lst = list(generate(framerate / frequency, int(framerate*len_),
                    volume,sampwidth,sine))
    data = bytes(lst)
elif sampwidth == 2:
    data = b'' # 16位
    lst = list(generate(framerate/frequency,
                        int(framerate*len_),
                        volume,sampwidth,sine))
    for digit in lst:
        data += struct.pack('<h',digit - 32768)

with wave.open(file,'wb') as f:
    # --snip-- (看前面)

PlaySound(file,SND_FILENAME)

使用matplotlib庫查看生成的聲波:

import matplotlib.pyplot as plt
# --snip--
plt.plot(range(len(lst)),lst)
plt.show()

Python 從零開始制作自己的聲音 - wave模塊讀寫wav文件詳解
寫在最后:
程序還可再做改進(jìn), 例如模擬各種樂器的音色, 也就是細(xì)微改變生成的聲波形狀。如果程序中加入共振峰, 還可實現(xiàn)簡單的語音合成?
但是, Windows系統(tǒng)已經(jīng)自帶了語音合成, 何必再開發(fā)一個呢?
下篇: Python 調(diào)用Windows內(nèi)置的語音合成,并生成wav文件文章來源地址http://www.zghlxwxcb.cn/news/detail-408294.html

到了這里,關(guān)于Python 從零開始制作自己的聲音 - wave模塊讀寫wav文件詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Python爬蟲進(jìn)階(1),Django+Selenium+Mysql+SimpleUI,從零開始搭建自己的爬蟲后臺管理系統(tǒng)

    Python爬蟲進(jìn)階(1),Django+Selenium+Mysql+SimpleUI,從零開始搭建自己的爬蟲后臺管理系統(tǒng)

    如果爬蟲做完的話都會發(fā)現(xiàn)每個文件要么保存到csv或者是其他格式的文件中,這樣做多少會有些麻煩,所以需要將這些內(nèi)容保存起來方便自己管理和查看內(nèi)容。 相對于flask而言Django有著相對成熟的一個后臺管理系統(tǒng)配合上其他一些插件就可以做到即插即用的效果而不用自己再

    2024年02月08日
    瀏覽(21)
  • 詳細(xì)步驟 | 打包制作自己的 Python 模塊包并上傳到 Pip 源 PyPI

    詳細(xì)步驟 | 打包制作自己的 Python 模塊包并上傳到 Pip 源 PyPI

    本文介紹如何打包一個簡單的 Python 項目,以及如何將其上傳到Python包索引平臺( PyPI ),供他人使用 pip install xxx 指令安裝。 文件目錄結(jié)構(gòu): 說明: packaging_tutorial 可以是任意的目錄名, pyproject.toml 是打包配置文件, src 里面存放的就是你的程序代碼, example_package_YOUR_USERNAM

    2024年03月24日
    瀏覽(19)
  • 從零開始快速構(gòu)建自己的Flink應(yīng)用

    從零開始快速構(gòu)建自己的Flink應(yīng)用

    本文介紹如何在 mac 下快速構(gòu)建屬于自己的 Flink 應(yīng)用。 在 mac 上使用homebrew安裝 flink: 查看安裝的位置: 進(jìn)入安裝目錄,啟動 flink 集群: 進(jìn)入 web 頁面:http://localhost:8081/ 基于模板直接構(gòu)建一個項目: 在項目的 DataStreamJob 類實現(xiàn)如下計數(shù)的功能: 在上面的例子中,我們使用

    2024年02月20日
    瀏覽(23)
  • 從零開始制作婚禮策劃展示小程序

    從零開始制作婚禮策劃展示小程序

    隨著移動互聯(lián)網(wǎng)的發(fā)展,小程序已經(jīng)成為各行各業(yè)展示和推廣自己的重要工具之一。對于婚禮策劃行業(yè)來說,制作一個專屬的婚禮策劃展示小程序,不僅能提升服務(wù)的專業(yè)性和便利性,還能吸引更多的客戶。下面將介紹從零開始制作婚禮策劃展示小程序的步驟。 第一步是進(jìn)入

    2024年02月16日
    瀏覽(23)
  • LeetCode 刷題記錄——從零開始記錄自己一些不會的

    LeetCode 刷題記錄——從零開始記錄自己一些不會的

    1. 最多可以摧毀的敵人城堡數(shù)目 題意 思路 兩層循環(huán),太low了 用一個變量記錄前一個位置 代碼 2. 到達(dá)終點的數(shù)字 題意 思路 代碼 3. 單詞的壓縮編碼 題意 思路 代碼 思路2 去找到是否不同的單詞具有相同的后綴,我們可以將其反序之后插入字典樹中。例如,我們有 “time”

    2024年02月09日
    瀏覽(46)
  • 小程序制作教程:從零開始搭建企業(yè)小程序

    小程序制作教程:從零開始搭建企業(yè)小程序

    在如今的數(shù)字化時代,企業(yè)介紹小程序成為了企業(yè)展示與推廣的重要工具。通過企業(yè)介紹小程序,企業(yè)可以向用戶展示自己的品牌形象、產(chǎn)品服務(wù)以及企業(yè)文化等內(nèi)容,進(jìn)而提高用戶對企業(yè)的認(rèn)知度和信任度。本文將介紹如何從零開始搭建一個企業(yè)介紹小程序。 首先,進(jìn)入喬

    2024年02月12日
    瀏覽(20)
  • 一篇SEO指南:新手如何從零開始優(yōu)化自己的網(wǎng)站

    一篇SEO指南:新手如何從零開始優(yōu)化自己的網(wǎng)站

    在如今的數(shù)字時代,擁有一個優(yōu)化良好的網(wǎng)站對于任何企業(yè)或個人來說都是至關(guān)重要的。但是,對于SEO新手來說,如何從零開始優(yōu)化自己的網(wǎng)站可能是一項看似艱巨的任務(wù)。在本文中,我們將為您提供一份SEO指南,幫助您了解從零開始優(yōu)化自己的網(wǎng)站的過程。 確定您的目標(biāo)關(guān)

    2024年02月02日
    瀏覽(29)
  • 構(gòu)建自己的ChatGPT:從零開始構(gòu)建個性化語言模型

    構(gòu)建自己的ChatGPT:從零開始構(gòu)建個性化語言模型

    ???? 博主 libin9iOak帶您 Go to New World.??? ?? 個人主頁——libin9iOak的博客?? ?? 《面試題大全》 文章圖文并茂??生動形象??簡單易學(xué)!歡迎大家來踩踩~?? ?? 《IDEA開發(fā)秘籍》學(xué)會IDEA常用操作,工作效率翻倍~?? ???? 希望本文能夠給您帶來一定的幫助??文章粗淺,敬

    2024年02月15日
    瀏覽(28)
  • 從零開始畫自己的DAG作業(yè)依賴圖(一)--前期準(zhǔn)備

    從零開始畫自己的DAG作業(yè)依賴圖(一)--前期準(zhǔn)備

    背景: 由于業(yè)務(wù)場景需要展示作業(yè)之間的依賴關(guān)系,由于一些開源的插件和當(dāng)前的業(yè)務(wù)邏輯有一些沖突,個人打算嘗試從零開始,一點點實現(xiàn)自己的DAG圖。同時用博客記錄自己實現(xiàn)過程和總結(jié),不正確的地方,歡迎指正提升。 場景分析: 數(shù)據(jù)開發(fā)中常常有作業(yè)之間的依賴,

    2024年02月05日
    瀏覽(27)
  • UE4從零開始制作數(shù)字孿生道路監(jiān)測平臺

    UE4從零開始制作數(shù)字孿生道路監(jiān)測平臺

    UE4集成Cesium for Unreal和WebSocket,后端使用NodeJs搭建服務(wù)器進(jìn)行數(shù)據(jù)模擬和真實數(shù)據(jù)實時轉(zhuǎn)發(fā)。 1:新建UE4項目并集成Cesium for Unreal Cesium for UE4插件解鎖了虛幻引擎中的3D地理空間生態(tài)系統(tǒng)。通過將高精度全尺寸WGS84 globe、開放API和空間索引開放標(biāo)準(zhǔn)(如3D圖塊)以及基于云的真實

    2024年02月02日
    瀏覽(49)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包