Audio

Audio

感受「聲音sound」是人類的本能。音樂、說話、風吹草動蟲鳴鳥叫等等聲響,都是「聲音sound」。

與科技裝置有關係的聲音,則稱作「聲音audio」。電視播放的聲音、電話通話的聲音等等,都是「聲音audio」。

Sample

聲音源自振動。耳膜感受空氣振動,在腦中產生聲覺。

要讓電腦處理聲音,必須預先讓聲音變成數字,也就是讓聲音經過「取樣sampling」與「量化quantization」兩個步驟。取樣把時間變成離散,量化把振幅變成離散。

先取樣(得到數列),再量化(四捨五入),最後得到一串整數數列。每個數字稱作「樣本sample」或「訊號signal」。

「取樣sampling」與「量化quantization」的關鍵參數:

duration持續時間:聲音總共多少秒。數值越高,訊號越多。

sampling rate取樣頻率:一秒鐘有多少個訊號。數值越高,音質越好。電腦的聲音檔案,通常採用48000Hz或44100Hz。手機與電話的聲音傳輸,公定為8000Hz。

bit depth位元深度:一個訊號用多少個位元記錄。數值越高,音質越好。電腦的聲音檔案,通常採用16-bit或24-bit。16-bit的每個訊號是[-32768,+32767]的整數,符合C語言的short變數。

channel聲道:同時播放的聲音訊號總共幾條。每一條聲音訊號都是一樣長。舉例來說,民眾所熟悉的雙聲道,其實就是同時播出兩條不同的聲音訊號。

取樣頻率、持續時間、聲道,相乘之後就是訊號數量。再乘以位元深度,就是容量大小。再除以8,可將單位換成byte。

順帶一提,不管是聲音或者是其他信息,只要是經過取樣與量化得到的資料,總稱PCM data。「脈衝編碼調變pulse-code modulation, PCM」源自訊號學,所以名稱才會如此不直覺。

Audio的資料結構

在電腦當中,聲音是很多串整數數列,資料結構是陣列。

各種聲音資料的取樣頻率和時間長度不盡相同。統合方式:動態陣列、可變長度陣列。

各種聲音資料的位元深度不盡相同。統合方式:採用32-bit浮點數,讀檔後將訊號數值縮放成[-1,+1],才進行聲音處理;存檔前調回原本範圍。

Amplitude

聲音訊號的數值,代表空氣振動的幅度。基準訂為0,範圍訂為±32767(當位元深度是16-bit)。也有人使用其他設定

振幅高,聽起來大聲。振幅低,聽起來小聲。

Frequency

人類擅於感受的不是振動的幅度,而是振動的頻率。

頻率高,聽起來尖銳。頻率低,聽起來低沉。

順便介紹「取樣定理」:x Hz的波,取樣頻率至少要是2x Hz,才能明確分辨上下次數,頻率保持相同(而振幅總是失真)。

也就是說,取樣頻率48000Hz,頂多只能記錄24000Hz以下的聲音。但是別擔心,人類聽覺範圍是20Hz至20000Hz。

使用C/C++處理聲音

C與C++本身沒有處理聲音的函式庫。

你可以土法煉鋼,選擇一種聲音檔案格式,例如WAV、MP3、AAC、FLAC,研讀其規格書,設計程式讀取聲音擷取訊號。

你也可以拍手煉成,直接使用現成的函式庫,例如AudioFileLAME,呼叫函式讀取聲音擷取訊號。

使用C/C++與作業系統處理聲音

只有「聲音播放器」和「聲音特效」,沒有「聲音訊號處理」。

你可以土法煉鋼,選擇一種作業系統,安裝其開發工具,使用其應用程式介面,播放聲音訊號、製造聲音特效。例如Windows API的XAudio2、Linux kernel的Advanced Linux Sound Architecture、MacOS使用的OpenALAudio Units、Android NDK的OpenSL ES

你也可以拍手煉成,直接使用功能齊全的工具,例如VSTRTAS

使用C#/Java/Qt處理聲音

讀取聲音,例如C#是援引Windows API、Java的AudioInputStream、Qt的QAudioInput與QAudioOutput。這些語言的處理機制都不一樣,自己看著辦吧。

播放聲音,例如C#的SoundPlayer、Java的AudioClip、Qt的QSound。這些語言的處理機制大同小異,函式名稱既統一又直覺,例如play、pause、volume、loop。

處理聲音。函式庫發展不完善,你必須自行編寫程式碼。

結果就是,學生和教師傾向使用MATLAB或Python。

使用Python處理聲音

Python本身擁有讀取聲音的函式庫wave

Python本身沒有播放聲音的函式庫,必須另行安裝。例如播放聲音playsound、即時播放聲音PyAudio

Python本身沒有處理聲音的函式庫,必須另行安裝。例如分析聲音pyAudioAnalysis、處理音樂librosa

使用HTML與JavaScript處理聲音:聲音播放器

以HTML建立<audio>,就能播放聲音。

以JavsScript動態建立<audio>,也能播放聲音。

先以HTML建立<audio>。再以JavaScript擷取<audio>,指定聲音檔案名稱。這種混搭風格,也能播放聲音。

重視網頁排版的情況下,適合使用混搭風格。

讓使用者自行選擇聲音檔案(甚至影片檔案)。

使用HTML與JavaScript處理聲音:聲音訊號

<audio>只是一個播放器。我們無法直接從<audio>得到訊號,必須額外使用AudioContext。

一、程式員事先指定檔案。寫作風格是新潮的promise串聯。

fetch()下載檔案
Response.arrayBuffer()取得檔案全文
AudioContext.decodeAudioData()擷取聲音訊號

二、使用者自行選擇檔案。寫作風格是古典的callback套娃。

<input>選擇檔案
FileReader.readAsArrayBuffer()取得檔案全文
AudioContext.decodeAudioData()擷取聲音訊號

三、儲存檔案。因為缺少AudioContext.encodeAudioData(),所以必須自己寫一個。我使用現成的riffwave.js,儲存成WAV。

RIFFWAVE.Make()生成檔案全文
其中RIFFWAVE.wav是檔案全文
其中RIFFWAVE.dataURI是超連結、附帶檔案全文
MouseEventst.initEvent()自動點擊超連結

瀏覽器為了安全起見,預設禁止讀取本機檔案。如果你想用本機檔案做實驗,你必須修改瀏覽器設定。做好實驗記得改回來。

Firefox
網址列輸入 about:config
security.fileuri.strict_origin_policy 的值改為 false

Chrome
命令列輸入 chrome.exe --allow-file-access-from-file

或者正常做法是建立本機網頁伺服器

使用HTML與JavaScript處理聲音:聲音工具組

方才介紹批次處理:一口氣取得所有訊號。現在介紹串流處理:不斷獲得一段訊號。

AudioContext的構造是圖論的有向無環圖。從起點一路串聯到終點,形成流程圖。

節點可以是聲音訊號(起點)。

MediaElementAudioSourceNode   播放器<audio>
MediaStreamAudioSourceNode    網路串流
OscillatorNode                波形產生器
AudioBufferSourceNode         自訂訊號

節點可以是聲音效果(中繼點)。

GainNode                      音量
ConvolverNode                 迴響
PannerNode                    指向
BiquadFilterNode              濾波器
AudioWorkletNode              自訂效果

節點可以是聲音效果的參數(起點)。

ConstantSourceNode            常數
AudioScheduledSourceNode      開關

節點可以是聲音輸出裝置(終點)。

AudioDestinationNode          喇叭
AnalyserNode                  頻譜
MediaStreamDestinationNode    錄音(存檔)

一旦開始播放起點之聲音訊號,就會自動套用中繼點之聲音效果。(至於合成效果,是將多個節點接往相同節點。)

起點是<audio>。

起點是波形產生器。

起點是自訂訊號。利用createBuffer()建立一串聲音訊號。利用createBufferSource()建立起點。

中繼點是音量。

中繼點是濾波器。

中繼點是自訂效果。過程非常麻煩,必須另外建立一個JavaScript檔案,利用AudioWorklet載入JavaScript檔案。

終點是頻譜。

終點是錄音。利用MediaRecorder,將一段一段的訊號,連成一整串訊號,便於存檔。

使用現成工具處理聲音

知名的聲音編輯軟體是AudacitySoX,聲音生成軟體是Pure Data

Audio Analysis

Audio Analysis

分析。擷取聲音訊號的特徵,例如振幅平均、頻率分布。

frame框

訊號很長,變化很大,因此必須將訊號分成小段處理,使得小段之內變化很小。每個小段都稱作一個「框」或「幀」。

當取樣頻率是48000Hz、框是512個訊號,則此框占有512/48000 ≈ 0.01秒,人耳無法分辨這麼短時間的變化,人聲也無法控制這麼短時間的變化,可以說是足夠細膩了。

為了讓變化更連續,於是讓框交疊。

short-time Fourier transform短時間傅立葉轉換

以下內容的先備知識是「Wave」。

聲音有兩個要素:振幅與頻率。訊號本身就是振幅,我們還想測量頻率。

聲音振動十分複雜,難以測量頻率。計算學家的共識是:運用離散版本的傅立葉轉換,將訊號數值分解成弦波,解析頻率。因為弦波是最漂亮的振動方式,所以適合當作公定標準。

擷取一個框,實施傅立葉轉換,大家特地稱作「短時間傅立葉轉換」。

spectrum頻譜

特定時間點的頻率分布圖。

實務上的做法是:截取一小段時間範圍的訊號,實施快速傅立葉轉換,得到每一種頻率的波的強度、相位。

比如48000Hz的取樣頻率、256點訊號,則頻譜總共256種頻率。第一種頻率是0Hz,接著每一種頻率相差48000Hz / 256 = 187.5Hz。

前128種、後128種左右對稱,後128種沒有實際作用。呼應取樣定理,資訊量只剩一半。

spectrogram頻譜圖

所有時間點的頻率分布圖。

三維的繪圖方式:如下面影片。

二維的繪圖方式:將強度長短改成亮度高低,讓一個頻譜變成一條垂直線,讓各個時間點的頻譜橫向拼成一個長方形。如下面動畫。

人類對於地震波的感覺是取log的。如同地震波,人類對於幅度與頻率的感覺也是取log的。有時候,頻譜、頻譜圖的座標軸會取log,以符合人類聽覺感受。

window窗

原本完整的聲音波形,硬生生被框截斷,頻譜將產生誤差。解法:將框的兩端的訊號漸漸減弱,減少影響。也就是乘上一個中央高、兩側低的函數,數值皆介於零到一之間,稱作「窗函數Window Function」。

filter濾波器

頻譜是分析聲音的工具。濾波器則是修改聲音的工具。

例如刪除聲音的高頻部分,稱作lowpass filter。

濾波器有時域與頻域兩大類。

時域濾波器,直接修改訊號。計算速度飛快。

頻域濾波器,藉由修改頻譜,間接修改訊號。一、原訊號,實施傅立葉轉換,得到頻譜。二、修改頻譜(例如把高頻的強度和相位調成0,形成lowpass filter)。三、新頻譜,實施逆向傅立葉轉換,得到新訊號。

Audio Synthesis

Audio Synthesis

合成。以建構組合的方式製作聲音。

聲音合成分為電路觀點、程式觀點,兩套學問大相逕庭。這裡只談程式觀點。

電路觀點:利用電子元件,以振盪器、濾波器製作聲音,發展成電子琴。
程式觀點:利用中央處理器,以弦波、數學運算製作聲音,發展成音樂編輯軟體。

前人研擬了許多種聲音合成的策略。加法合成是最基本的策略。

   additive synthesis:加法合成。疊加許多個波。
subtractive synthesis:減法合成。利用濾波器,刪除某些頻率。
   granular synthesis:顆粒合成。堆砌一丁點長度的聲音。特色是嘈雜。
  wavetable synthesis:建立聲音波形的資料表,直接套用現成的波形。

Virtual Musical Instrument

虛擬樂器。合成樂器聲音。已有專著函式庫程式語言

前人創造了兩種合成樂器聲音的原理:弦波、數位波導。

simple harmonic wave:調整弦波,產生電子樂器聲音。

弦波是最理想的振動方式。根據「傅立葉級數」,任意數列皆可拆解成不同頻率的弦波。因此有人認為,反向操作,疊加各種頻率的弦波,可以生成各種聲音。這是我設計的一套練習題

digital waveguide:模仿管弦的振動方式,產生管弦聲音。

吉他(撥弦plucked string)、提琴(弓弦bowed string)、鋼琴(槌弦hammered string)、長笛(木管woodwind)、小號(銅管brass)、大鼓(打擊percussion),各種樂器有各種演算法。

Sound Effect

Sound Effect

效果。修改聲音,呈現其他風格。

電路觀點已有專著。程式觀點請見下文。

首先來個範本:「紅豆生南國,春來發幾枝」。

gain增益

調整波形,振幅乘上倍率,振幅伸展或壓扁。音量放大或縮小。

normalization標準化

校準波形,中央為0,最大振幅為1。音量盡量調到最大聲。

pre-emphasis預強調

有時候錄音環境不佳,錄製到的聲音濛濛霧霧。微分運算可使聲音清晰。副作用是音量下降。

連續函數的情況下,弦波,微分之後,仍是弦波。離散數列的情況下,波形稍微失真,但是無傷大雅。

smoothing柔化

有時候錄音環境不佳,錄製到的聲音唧唧吱吱。平均數可抑制雜訊。副作用是聲音模糊不清、音量下降。

連續函數的情況下,弦波,取區間平均數,仍是弦波。離散數列的情況下,波形稍微失真,但是無傷大雅。

mixing混音

混和好幾道聲音。加權平均數。

為了避免超過數值上下限,為了維持原音量、原音色,有時會做複雜的處理

echo回聲

相同聲音稍後再度出現。延遲與混音。位移與疊加。

將反射路徑改成直線,可以發現回聲的本質:不同地點的聲音,抵達人耳時有時間差。聲音接觸牆壁,牆壁吸收部分能量,導致音量降低。實作方式很簡單:位移、縮放、疊加。

reverb迴響

餘音繞樑。反覆回音,間隔極短。

聽起來彷彿位於寬敞的密閉空間。台灣卡拉OK經典音效。正港台灣味。

pitch shifting移調

改變頻率。調整播放速度(伸縮時間軸),頻率就改變。副作用是聲音長度也改變。比較理想的演算法,請見後面章節。

chorus合唱

混和好幾道聲音,其頻率略有變動、其延遲時間略有差異。

harmonics和聲

混和好幾道聲音,其頻率皆不同。

想要好聽的和聲,必須按照樂理,選擇適當音階(請見後面章節)。現在的流行音樂,幾乎每一首歌都套用和聲效果來修飾聲音。

robot sound機器人聲

簡易做法是混和兩道聲音:頻率略高、頻率略低的聲音。

根據數學公式cos(a)cos(b) = cos(a-b) + cos(a+b),一個弦波,乘上另一個弦波,就得到頻率略高、頻率略低的兩個弦波疊加在一起。這個技術其實就是AM,收音機的調幅。

根據傅立葉級數,原訊號可以看成一群弦波疊加。根據分配律,原訊號乘上一個弦波,可以看成一群弦波個別乘上一個弦波,最後再疊加。

tremolo震音

振幅振動。即是收音機的調幅AM:振幅乘上弦波。

震音是演奏技巧。快速連彈同一根弦,導致音量忽大忽小。

小提琴可以達成柔順的震音(途中沒有attack)。吉他無法避免重新撥弦的音量(途中不斷attack)。此處的震音特效可以達成柔順的震音。

vibrato顫音

頻率振動。即是收音機的調頻FM:頻率乘上弦波。

顫音是演奏技巧。按弦後,手指來回滑動。

適度調整頻率振動範圍、頻率振動週期,捶弦、推弦、滑弦摩擦聲,這些fingerstyle的常見音色,幾乎都可以製造出來。

phasing移相

混和兩道聲音,原本聲音、相位相差一點點的聲音(極短延遲),通常設定成1毫秒。

兩個弦波,振幅相同,頻率相同,相位略有差異。兩個弦波疊加,還是弦波。若相位差是零,則振幅翻倍。若相位差是半個波長,則振幅抵消。若相位差只有一點點,則振幅和頻率變動一點點。

根據傅立葉級數,原訊號可以看成一群弦波疊加。現在讓這些弦波共用同一種相位差。頻率越高,波長越短,振幅抵消的機會變多了。也就是說,高頻弦波被大量刪除,其餘弦波的頻率都會變動一點點。最後導致高音減少、音準失準。

大家習慣額外補強。一、連做四次,最後跟原本聲音合成。可讓聲音變飽滿。二、讓相位差來回飄移。可讓聲音變自然。

聽起來嗚嗚的,像是對著鐵管說話。電子吉他經典音效。

flanging鑲邊

混和兩道聲音,原本聲音、零個波長至半個波長的延遲聲音。如果知道聲音主要頻率,那就取其波長,適度加減;如果不知道,那就設定成20毫秒以內。

大家習慣額外補強。一、讓相位差來回飄移(延遲時間來回飄移)。二、加上強烈迴響。

聽起來歪依歪依的。電子吉他經典音效。

distortion失真

降低聲音品質,聽起來像破音。

失真方法非常多,這裡介紹三個:量化、截斷、過載。

quantization量化

16-bit改成8-bit,甚至更低。

聽起來哧哧的,宛如收音機。

clipping截斷

振幅乘上一個比較大的倍率,讓振幅超過±32767並且截斷。

聽起來嘩嘩的,宛如耳機摔壞。

overdrive過載

音量開到極限,音箱產生破音。一、振幅越大、失真越大。二、以reverb模擬音箱迴響。三、以clipping模擬音量極限。

聽起來很吵。電子吉他經典音效。

equalization等化

調整每個頻帶的音量,使得聽起來均勻。套用許多個濾波器即可。

人類聽覺對於每種頻率的音量感受能力都不同,機制十分複雜,難以設計演算法。目前是由專業的錄音師,手動調整各頻帶音量。前面的影片就是一個示範。

wah-wah哇哇

用濾波器放大某段頻帶的聲音。隨著時間,頻帶來回移動。

聽起來哇哇叫。電子吉他經典音效。

pitch bending滑音

頻率平滑地增減(頻譜的強度平滑地位移)。【查無資料】

morphing變形

一種聲音,平滑柔順地轉化成另一種聲音。推測是每個頻帶各自轉音。【查無資料】

Sound Design

Sound Design

設計。綜合上述技巧,創造各式各樣的聲音。

甚至根據人類對於聲音的感受,利用聲音傳遞訊息、溝通互動。例如有人研究什麼是舒服的聲音什麼是恐怖的聲音

已有專著。這裡就不整理了。

Music🚧

Music

音樂。遵守規律的聲音。

聲音的要素:pitch、timbre、loudness、duration
音樂的要素:beat、rhythm、melody、harmonics

音樂家認知中的音樂,就是讓以上要素遵守規律、遵守樂理。

例如pitch遵守十二平均律、duration遵守全音符、二分音符、四分音符,harmonics遵守大調、小調。

聲音訊號的要素:amplitude(volume)、frequency(pitch)、waveform(timbre)

然而計算學家別無選擇,只能從聲音訊號下手,從volume和pitch這兩條路線開始發展。

Volume

音量。振幅決定音量。

大家傾向用平均振幅作為音量。舉例來說,正弦波的平均振幅等於最大振幅開根號。

volume和loudness不一樣。volume是聲音訊號本身的大小聲,loudness是人耳感知到的大小聲。人類的聽覺系統,對於相同音量、不同頻率的聲音,聽到的是不同響度的聲音。

Pitch

音高。聲音聽起來的高低。音高高則尖銳。音高低則低沉。

關於振幅高低,有volume和loudness兩個詞彙可以區分實際高低和聽覺高低。然而,關於頻率高低,只有pitch一個詞彙,代表聽覺高低;於是計算學家只好把pitch也當作實際高低。

音樂當中,音高必須符合音階。Do Re Mi Fa Sol La Si。人類研究了數百年,總結出「十二平均律」,建立了音階與頻率的對應表。每個音階的頻率是固定值,而且組合起來特別好聽。

一、任何一個音階,
  頻率乘以二(琴弦長度變一半),升為高音。
  頻率除以二(琴弦長度變兩倍),降為低音。
二、以440Hz為基準,叫做中音A。
  也就是說,高音A是880Hz,低音A是220Hz,更低音A是110Hz。
三、兩個A之間,切成12段。考慮頭尾,總共13個音階。
  音階包含A B C D E F G。其他音階用升降記號♯和♭表示。
四、為了區別高中低音,於是補上數字。
  以C為開端,不是以A為開端。
  中音是數字3。高音加1。低音減1。

Timbre

音色。聲音的波形。振幅與頻率的複合。

使用現成工具處理音樂

函式庫librosaEssentiamadmomMARSYASSoundTouch

Music Analysis🚧

Music Analysis

音樂檢索會議MIREX可以找到歷年熱門主題。

ADSR Envelope: attack decay sustain release

一個數學模型,用來描述樂器演奏一個音符的音量變化。可進一步用來分辨樂器。

敲擊琴鍵時,振幅急遽上升、急遽下降。按住琴鍵時,振幅幾乎不變。放開琴鍵時,振幅快速下降,直至歸零。

為了更加擬真,像是Yamaha電子琴甚至推廣到八段變化。

Onset Detection

發聲偵測。給定聲音訊號,找到音符的開始時刻、結束時刻。

稍微介紹幾個常見名詞:

onset:聲音開始時刻。
offset:聲音結束時刻。
energy:能量=頻域平方和=時域平方和。
rms:能量除以訊號長度再開根號。

相鄰兩幀,離散傅立葉轉換,得到強度頻譜,觀察每個頻率的強度變化。由於無法預測音高、預測頻率,只好窮舉並累計每種頻率的強度變化。

每個時刻,分別計算強度變化量,得到「發聲偵測函數Onset Detection Function」。實施peak detection,得到音符出現時刻。

《Multi-Feature Beat Tracking》整理了常見的發聲偵測函數。

spectral flux:相鄰兩幀,強度頻譜的強度上升量總和。下降量不計入。
     ODF(t) = sum max(0, |Xt(f)| - |Xt-1(f)|)
               f
log spectral flux:強度頻譜事先取log,以符合人類聽覺感受。
     ODF(t) = sum max(0, log(|Xt(f)|) - log(|Xt-1(f)|))
               f
bonk~:訊號套用Hann窗函數。強度頻譜點對點相除(省得取log),商大於1則計入總和。
     ODF(t) = sum w(f) max(0, |Xt(f)| / |Xt-1(f)| - 1)
               f
bark~:bonk~加強版,頻帶採用Bark's frequency scale。

Beat Tracking / Rhythm Extraction / Tempo Estimation

節拍偵測。給定聲音訊號,找到音符們的間隔時間。

韻律擷取。偵測一連串的節拍。

速度估計。推定標準節拍時間。

dynamic programming:spectral flux追蹤peak。教學講義。
            懲罰函數是log-Gaussian,其平均數是當前最佳間隔時間。
IBT:spectral flux autocorrelation追蹤peak。同時,頻譜能量足夠大。
OBTAIN:細部改良。例如窗函數、發聲偵測函數、懲罰函數。
HMM:動態規劃改成HMM。並且追加其他偵測項目。
DBNBeatTracker:神經網路。

Formant

不同樂器演奏相同音階,聽起來都不一樣。一個原因是ADSR,另一個原因是附帶其他頻率。根據駐波現象,基本頻率的正整數倍,都會一起出現;通常標記為F0、F1、F2、……,其中F0是基本頻率,F1是兩倍,F2是三倍,以此類推,統稱「共振峰」。

相同樂器演奏相同音階,聽起來也可能不一樣。例如銅管樂器的送氣強弱,就會改變駐波、改變共振峰。

目前實驗都是選擇特定時刻的波形。似乎尚未有人研究形成駐波的過程、形成特定音色的原因。如果你知道請告訴我。

Formant Detection / F0 Detection

共振峰偵測。求出特定時刻(實務上是一幀)的共振峰。

有時我們只在意F0。

在時域,多種頻率以不同強度疊合,波形複雜,無法精準辨認波長。先前介紹的frequency detection演算法效果不佳。

在頻域,由於離散傅立葉轉換的缺點spectral leakage,頻譜無法精準呈現駐波現象。先前介紹的peak detection演算法效果不佳。

尋找F0極度困難。理想的做法是捨棄演算法,改以物理儀器測量F0。但是對於已經數位化,儲存成WAV、MP3格式的聲音,我們別無他法,只能從聲音訊號下手,設計演算法去估計F0。

gcd:頻域所有峰的最大公因數。誤差很大。
cepstrum:倒頻譜,第一個高峰就是F0。誤差很大。
Maher–Beaucham:試誤法猜F0。
                針對一個F0,算F0...Fn跟頻域所有峰的匹配誤差,找誤差最小者。
DIO:許多個bandpass filter (Nuttall window),一個濾波器得到一個F0。
     峰到峰、谷到谷、零到零(上坡)、零到零(下坡),一共四個波長。
     四個波長平均數,當作F0。
     四個波長變異數,最小的當作最佳F0。

Formant Tracking / F0 Tracking

共振峰追蹤。求出每個時刻(實務上是每一幀)的共振峰。

有時我們只在意F0。

困難點:一、波形複雜,F0容易誤認為原本的兩倍或者一半。二、attack與decay時期,駐波尚未到達穩態,共振峰變化大。三、release時期,駐波消逝,共振峰不明顯。

實務上是用dynamic programming、hidden Markov model預測F0走向。

RAPT:動態規劃。自己看。

Pitch Tracking / Melody Extraction / Chord Recognition

音高偵測。給定聲音訊號,找到音符們的頻率高低。

旋律擷取。偵測一連串的音高。

和弦辨識。偵測一整組的經典音高分布。

monophony:單音。一次演奏一個音階。
polyphony:複音。同時演奏多個音階。

複音更難追蹤音高。大家正在研究當中。

Pitch Shifting(Pitch Modification)
Time Stretching(Time-scale Modification)

伸縮時間軸,重新取樣,就能同時改變音高與長度。前面章節曾經提到過。

如果只想改變音高,或者只想改變長度呢?我們可以運用分治法的概念,將聲音訊號切成小段處理。

一、音高改變,長度不變:每框分別伸縮,然後疊加。

二、長度改變,音高不變:每框分別位移,然後疊加。

重疊之處,影響音質,必須克服,因而發展一系列演算法:

OLA:疊加。淡入淡出,可採用三角窗(一次內插)或者Hann窗。
SOLA:找到重疊誤差最小的位置,例如correlation最小。
PSOLA:找epoch/F0 peak、建框(以peak為中心)、套窗、移位、疊加。

上述演算法都在對抗重疊問題。有人將聲音訊號進行傅立葉轉換,微調每個框的每個頻率的相位,令波形銜接,解決重疊問題。

phase vocoder:在頻域處理,微調相位,讓波形連續。

最後補充一下。調音高和調長度這兩個問題,解決其中一個,就可以間接解決另一個。首先伸縮時間軸,讓音高和長度皆改變,然後用一調回原本音高,就是二;用二調回原本長度,就是一。

實務上是直接的方式好呢?還是間接的方式好呢?我不清楚。

Pitch Bending

滑音。頻率平滑變動。我查不到任何演算法。

glissando:兩個音階之間,彈奏所有音階。離散。
portamento:兩個音階之間,音高圓滑變動。連續。
            吉他就是按著弦滑動。鋼琴沒辦法。
legato:數個音階,只有一次attack。聲音連續不斷。
        吉他是撥一次弦,按很多次弦。
        鋼琴不得不按鍵,只能按了下一個、才放上一個,越按越小力,慢慢放開踏板,
        聽起來彷彿只有attack一次。
vibrato:音高抖動。
         吉他就是按弦並揉弦。鋼琴沒辦法。

Music Composition🚧

Musical Composition

電腦作曲。有趣的軟體如PixiTracker、Online Sequencer。

Algorithmic Composition

電腦自動作曲。例如虛擬的作曲家Emilly Howell。

Musical Instrument Recognition

樂器辨識。給定聲音訊號,判斷是哪種樂器的音色。

Audio Restoration

修復。已有專著

Audio Multitrack Recording

多種聲音合成一段聲音。即是先前介紹的「混音mixing」。

目前做法是使用音樂編輯軟體,混合所有聲音。可以自己扮演全部角色,也可以在網路上和陌生人組成一個樂團。關鍵字multitrack acapella、multitrack cover。

Audio Source Separation

一段聲音分成多種聲音。

目前做法是non-negative matrix factorization、錄製各種樂器的聲音在頻域實施比對。

Score-to-Audio Alignment

樂譜變成聲音訊號。

記載音樂,大家一律使用數學符號,不過不是大家從小到大慣用的數學符號,而是小豆芽、五線譜。

播放真實的樂器聲音:http://onlinesequencer.net/

電腦合成的樂器聲音:檔案格式MIDI。

Audio-to-Score Alignment(Score Following)

聲音訊號變成樂譜。難度很高。

Audio-to-Audio Alignment(Melody Recognition)

聲音訊號與聲音訊號的對齊。相仿的概念有哼唱選歌、旋律辨識、以聲音搜尋聲音。

目前做法是比對數列的演算法dynamic time warping、分類數列的演算法hidden Markov model等等。

Audio Feature Description(Audio Identification)

特徵描述。找到聲音的重點,以數值形式記錄下來。

倒頻譜cepstrum:FT → abs → log → IFT → abs。頻譜的絕對值(或絕對值平方)取log,實施逆傅立葉轉換。

bark frequeney scale是人類聽覺系統擅於感知的24個頻帶。

MFCC, Mel-frequency cepstrum coefficients:模擬人耳聽覺系統,擷取各個頻帶的強度。

HPCP:音樂的調性。

Audio Genre Classification

依照曲風實施分類。

Audio Emotion Recognition

感情辨識。已有專著