又用Mathematica寫了一段卡農(nóng)

你能在這里聽到它

用數(shù)學軟件演奏音樂早已不是什么新鮮事,很早就有人用Matlab彈奏卡農(nóng)或是最炫民族風,最近我知道還有人用無理數(shù)生成一段音樂,很有趣。而我選擇用Mathematica彈奏卡農(nóng)是因為卡農(nóng)這種譜曲方式很奇妙,體現(xiàn)在程序上也會是簡潔而優(yōu)美的??赡苡腥诉€不了解卡農(nóng)是什么,卡農(nóng)不是指某一首曲子,而是一種譜曲方式,它把幾段相同的旋律在不同的時刻依次展開,交錯的旋律又能相互配合,形成一首完整的卡農(nóng)。這用Mathematica演奏的卡農(nóng)就是大家最耳熟的“帕赫貝爾的卡農(nóng)”,你可以在它的樂譜中一窺其中的奇妙。


我們關(guān)注的重點是,這首卡農(nóng)有三個聲部(在樂譜上對應(yīng)著前三排)和一個背景旋律,但實際上三個聲部演奏的旋律是相同的,所以我們只需要輸入一個聲部的譜子,然后讓三個聲部在不同的時間進入就可以了。

手動輸入樂譜——失敗

起初我在網(wǎng)上找到的是巴赫的手稿,當我把一個聲部的旋律都輸入進去后,最終的效果并不是很理想,我想這個譜子更適合音樂會彈奏,需要樂手控制不同聲部的音量與節(jié)奏,但這在Mathematica上很難實現(xiàn)。


從Matlab到Mathematica

后來我在網(wǎng)上發(fā)現(xiàn)了一個用Matlab彈卡農(nóng)的程序,聽過之后,感覺他的譜子更適合用軟件演奏。就決定把Matlab代碼翻譯到Mathematica上。首先我們分析一下Matlab的代碼

Matlab代碼

Matlab中的代碼一共分三部分

1. 告訴電腦如何彈奏音符

2. 輸入一個聲部的旋律

3. 組合三個聲部

1.告訴電腦如何彈奏音符

我們需要告訴電腦

i.音符名稱(do,re,mi,fa...)

ii.音符持續(xù)的時間(音符時值t)

iii.音調(diào)(頻率f)

所以我們輸入的應(yīng)該是如下格式的信息:

????????????????????????????????????????????音符名稱=sin(2πft)

看看這在Matlab中是如何做到的

% 1/4 notes

do0f = mod4.*cos(2*pi*ScaleTable(21)*f0*t4);

re0f = mod4.*cos(2*pi*ScaleTable(22)*f0*t4);

mi0f = mod4.*cos(2*pi*ScaleTable(23)*f0*t4);

% 1/8 notes

fa0e = mod8.*cos(2*pi*ScaleTable(1)*f0*t8);

so0e = mod8.*cos(2*pi*ScaleTable(2)*f0*t8);

la0e = mod8.*cos(2*pi*ScaleTable(3)*f0*t8);

% 1/16 notes

fa0s = mod16.*cos(2*pi*ScaleTable(1)*f0*t16);

so0s = mod16.*cos(2*pi*ScaleTable(2)*f0*t16);

la0s = mod16.*cos(2*pi*ScaleTable(3)*f0*t16);

初看感覺很復雜,但其實它的形式和上面的公式是相同的

i.do0f,re0f,mi0f...代表音符名稱

ii.ScaleTable(\space)*f0代表頻率f,不同音符的ScaleTable()不同

iii.t4,t8,t16代表持續(xù)時間$t$,更具體的,t4=0.5s,t8=0.25s,t16=0.125s

但我們還發(fā)現(xiàn)他多出一個mod函數(shù),這其實是一個修正函數(shù)(modify),乘上他之后可以讓波形變得更柔和,有漸入漸出的效果。


未經(jīng)mod修正過的波形
經(jīng)mod修正過的波形

mod后面的數(shù)字代表對應(yīng)音符的持續(xù)時間。比如mod4要和t4相乘。

2. 輸入一個聲部的音符

這一步就很好理解了,這首卡農(nóng)背景旋律(Base Melody)由大提琴演奏,主旋律(Long Melody )由三把小提琴演奏,我們分別命名cello和violin

% Base Melody

cello = [do1f do1f so0f so0f la0f la0f mi0f mi0f... fa0f fa0f do0f do0f fa0f fa0f so0f so0f];......

% Long Melody

violin = [mi2f mi2f re2f re2f do2f do2f ti1f ti1f... la1f la1f so1f so1f la1f la1f ti1f ti1f ......

3.組合三個聲部

正如我前面說的,我們只需要在不同的時間點加入相應(yīng)的旋律,就像下面這樣(blkblock代表空白音符)

% violin1

v1 = [blkblock violin blkblock blkblock];

% violin2

v2 = [blkblock blkblock violin blkblock];

% violin3

v3 = [blkblock blkblock blkblock violin];

% Combination

s = c1+v1+v2+v3;

sound(s,fs);

這樣就得到了一段能在Matlab上演奏卡農(nóng)的代碼,接下來就要把它翻譯到Mathematica上。

翻譯到Mathematica

我們當然要借助Mathematica來翻譯,思路跟Matlab上的思路一樣

1.建立音符名稱和聲音的關(guān)聯(lián)(Association)

最終的關(guān)聯(lián)應(yīng)該像下面這樣。我給這個關(guān)聯(lián)起名叫“asswecan”,意思是用這個關(guān)聯(lián)我們能做到「音符名稱到聲音的轉(zhuǎn)換」,記住這個名字,我們之后會用到。


那么要如何生成這個關(guān)聯(lián)呢?首先我們需要生成聲音,這里用到Play函數(shù):


一個頻率為440Hz的“中音A”的波形

根據(jù)Matlab代碼中的音符信息「ScaleTable(),f0,t4,t8,t16」改變Play函數(shù)中的參數(shù)來發(fā)出不同的音調(diào),替換的關(guān)系是這樣的:


有了這個思路,就可以用StringReplace函數(shù)進行替換了。

2.輸入一個聲部的旋律

Matlab中的旋律代碼有許多多余的字符,需要我們處理一下

i.輸入Matlab代碼中的旋律

cellonoteinfo =

"do1f do1f so0f so0f la0f%% la0f mi0f mi0f...fa0f%% fa0f do0f do0f fa0f \n

fa0f so0f so0f";

這里面有很多我們不希望得到的 ... %% 空格回車這樣的字符,需要把他們?nèi)サ簟?/p>

ii.定義去掉無用字符的函數(shù)

infotonote[info_] :=

StringPartition[StringJoin@StringCases[info, _?LetterQ | _?DigitQ],4];

iii.得到適用于Mathematica的旋律

In[1]:= cellonote = infotonote[cellonoteinfo]

Out[1]:= {"do1f", "do1f", "so0f", "so0f", "la0f", "la0f", "mi0f", "mi0f", \

"fa0f", "fa0f", "do0f", "do0f", "fa0f", "fa0f", "so0f", "so0f"}

這樣我們就得到了旋律中的音符名稱列表

3.用聲音替換旋律中的音符名稱

還記得那個"asswecan"嗎?它可以把音符名稱替換成聲音。用“asswecan”關(guān)聯(lián)完成對幾段旋律的轉(zhuǎn)換,并規(guī)定好他們開始彈奏的時間,比如vio1末尾的8就代表第一把小提琴在第8秒才開始彈奏。

cello = Sound[Flatten@Table[Replace[cellonote, notetosoundass, 1], 23], {0}];

vio1 = Sound[Replace[violinnote, notetosoundass, 1], {8}];

vio2 = Sound[Replace[violinnote, notetosoundass, 1], {16}];

vio3 = Sound[Replace[violinnote, notetosoundass, 1], {24}];

4.最后把他們組合起來

As we can see, 我們完成了!

你可以在B站聽到這段旋律

你也可以前往Wolfram社區(qū)下載Matlab及Mathematica代碼文件

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 要在計算機內(nèi)播放或是處理音頻文件,也就是要對聲音文件進行數(shù)、模轉(zhuǎn)換,這個過程同樣由采樣和量化構(gòu)成,人耳所能聽到的聲...
    Viking_Den閱讀 10,570評論 1 10
  • 無損壓縮是在保證不損失源文件所有碼率的前提下,將音頻文件壓縮的更小,也就是說這兩種音頻格式都能保證源文件碼率的無損...
    風起云涌Hal閱讀 9,041評論 1 3
  • 前言 說到視頻,大家自己腦子里基本都會想起電影、電視劇、在線視頻等等,也會想起一些視頻格式 AVI、MP4、RMV...
    ForestSen閱讀 23,975評論 10 203
  • 最近在折騰itunes音頻處理(裁剪編輯,格式轉(zhuǎn)換,波形繪制) 音頻的一些概念 對每個音頻文件有兩部分:1是文件格...
    osbornZ閱讀 2,422評論 1 5
  • 湖畔松間道,微風拂六出。 寒夜未央急展俏,一點北國素。 也擬爭芳意,卻壓墻角竹。 閨樓佳人朝梳頭,消失...
    茶詩閱讀 234評論 0 0

友情鏈接更多精彩內(nèi)容