週末了給你們整點有趣的東西吧,在不借助電腦聲卡的狀況下,只利用電腦主板上的蜂鳴器,就能讓電腦本身哼起歌來,感受還挺好玩的呢~
廢話很少說,讓咱們愉快地開始吧~python
Python版本:3.6.4web
相關模塊:編程
PyQt5模塊;函數
以及一些python自帶的模塊。工具
安裝python並添加到環境變量,pip安裝須要的相關模塊便可。學習
原理其實挺簡單的,主要就是利用python來控制電腦主板上的蜂鳴器以不一樣的頻率發出聲音從而模擬人哼歌時的效果~開發工具
具體而言,咱們小學就學過,聲音是由物體震動產生的,它包括如下幾個部分:大數據
1. 音調: 聲音的高低,由發聲體的振動頻率決定,頻率越高,音調越高; 2. 響度: 人耳感受到的聲音的大小,它跟發聲體的振幅有關.振幅越大,響度越大;振幅越小,響度越小; 3. 音色: 發聲體的聲音品質,由發聲體自己的特徵決定.是區別聲音的重要標誌.
這是考點,麻煩還在念初中的粉絲記一下,考試要考的,別一到週末了就只玩手機不學習~
對於電腦主板上的蜂鳴器來講,音色和響度基本上已經肯定無法改了,因此咱們只能在頻率上動腦筋,從而讓蜂鳴器哼出咱們想要聽的歌來~3d
具體而言,咱們能夠調用這個函數來讓蜂鳴器哼歌:code
1 import ctypes 2 beep_player = ctypes.windll.kernel32 3 beep_player.Beep(freq, beats)
其中freq表明頻率,beats表明節拍(就是當前音符播放的時長)。好的,看到這裏可能有人懵了,別急,讓我來舉個例子說明咱們到底應該怎麼作。
首先,咱們去網上找一首喜歡的歌的音樂簡譜,這裏以小幸運爲例:
能夠發現簡譜上有數字1234567這7個基本音符,唱做:
1 1: do 2 2: re 3 3: mi 4 4: fa 5 5: sol 6 6: la 7 7: si
每一個基本音符表明聲音的一個頻率,在基本音符上方標記"·"時,則表明該音升高一個八度,稱爲高音,反之則表明該音下降一個八度,稱爲低音(這裏就不考慮倍高音和倍低音的狀況了):
通常而言,咱們能夠假設高音do的頻率是do的兩倍,是低音do的四倍,其餘音符相似。再根據十二平均律:
1 一種音樂的定律方法,將一個八度平均分紅十二等份, 2 每等分稱爲半音,是最主要的調音法。 3 音高八度音指的是頻率加倍(即二倍頻率)。 4 八度音的頻率分爲十二等分,便是分爲十二項的等比數列, 5 也就是每一個音的頻率爲前一個音的2的12次方根: 6 其近似值約爲2^(1/12) = 1.06
咱們只須要知道do的頻率,就能夠推算出其餘音符的頻率了(好比do的頻率是1,那麼re的頻率就是11.061.06)。通常而言,do的頻率和簡譜中的調號的對應關係以下:
1 'C': 523, 2 'D': 587, 3 'E': 659, 4 'F': 698, 5 'G': 784, 6 'A': 880, 7 'B': 988
ok,至此,咱們搞定了freq,如今再來看beats。在簡譜中,通常經過加"·"和短橫線"-"來表示音的長短:
1 1. 在基本音符右側加記一條短橫線, 表示增加一個四分音符的時值 (就是這個音的長度*2) 2 2. 在基本音符下方加記一條短橫線, 表示縮短原音符時值的一半 3 3. 音符X右側加·時表明增加原音符時值的一半 4 4. 在簡譜中, 大於四分音符的單純音符一般不加記·,即用X--來表示X-·
盜個圖更直觀一點說明吧:
OK,如此一來,咱們就能夠很輕鬆地肯定上面的音樂簡譜中每一個音符的freq和beats,從而調用函數讓蜂鳴器哼出這個音符來了,因此音符連起來哼不就等於讓蜂鳴器哼歌了嘛~
爲了方便程序肯定每一個音符的freq和beats,咱們把簡譜重寫一下,就像這樣:
即每一個音符由三個元素組成:
[基本音符][低音/中音/高音][音的長度]
而後寫過函數解析一下:
1 '''解析''' 2 def parse(self, filepath): 3 song_info = open(filepath, 'r').read().replace('\n', '').split(',') 4 tone = song_info[0] 5 song_info = song_info[1:] 6 return tone, song_info
並根據解析結果播放就ok啦:
1 '''播放''' 2 def play(self): 3 filepath = self.musicfilepath_edit.text() 4 if not os.path.isfile(filepath): 5 return 6 tone, song_info = self.parse(filepath) 7 do = self.tone2freq_dict[tone] 8 re = int(do * self.tone_scale * self.tone_scale) 9 mi = int(re * self.tone_scale * self.tone_scale) 10 fa = int(mi * self.tone_scale * self.tone_scale) 11 sol = int(fa * self.tone_scale * self.tone_scale) 12 la = int(sol * self.tone_scale * self.tone_scale) 13 si = int(la * self.tone_scale * self.tone_scale) 14 notes = [0, do, re, mi, fa, sol, la, si] 15 for item in song_info: 16 if notes[int(item[0])] == 0: 17 time.sleep(self.beats / 1000) 18 else: 19 self.beep_player.Beep(int(notes[int(item[0])]*self.pitchs_dict[item[1]]), int(self.beats * float(item[2:])))
文章到這裏就結束了,感謝你的觀看,關注我天天分享Python小工具系列,下篇文章根據中文姓名猜想對方性別
爲了感謝讀者們,我想把我最近收藏的一些編程乾貨分享給你們,回饋每個讀者,但願能幫到大家。
乾貨主要有:
① 2000多本Python電子書(主流和經典的書籍應該都有了)
② Python標準庫資料(最全中文版)
③ 項目源碼(四五十個有趣且經典的練手項目及源碼)
④ Python基礎入門、爬蟲、web開發、大數據分析方面的視頻(適合小白學習)
⑤ Python學習路線圖(告別不入流的學習)
⑥ 兩天的Python爬蟲訓練營直播權限
**All done~完整源代碼+乾貨詳見我的主頁簡介或是私信獲取