創作內容

2 GP

10/17~10/20,極短期計劃,麥克風錄音轉音階,修正之前理解錯誤,但效果還是不好

作者:李兒諳│2018-10-17 17:44:17│巴幣:4│人氣:183
10/20網頁麥克風錄音轉音階並存檔"(慘不忍睹),但就先這樣吧
昨天getByteFrequencyData(dataArray),每個所記錄的0~255猜測應該是振幅大小
陣列索引*取樣率/fftSize才是該Hz的
程式修改下後有好些,但音還是不準(因為我還是用取振幅max為準的做法)

若要改良的話~我想大概得兩段式
一段是錄音,然後把錄音檔傳上網頁,才能慢慢分析
(因為實時分析產生對應音階,總覺得運算速度沒那麼快)
所以若這篇以後有更新的話
大概就是
1.針對傳的檔案顯示頻譜
2.找出雜訊的頻譜特徵並過濾掉
3.找出人聲或樂器的特徵,化為較準確的音階
雖然對我而言
找出頻譜特徵相關的
我都不知道該怎麼做!!

若要比較好用的網站,在線測音高(錄音樂檔可用Audacity或本文Go語言的方法)
會發現這網站是因為不知道頻率資料要怎麼轉成音高,找資料過程中時發現的
意外的發現我以前其實是有看過那篇文章的(因為知乎文章點過贊同了)
只是我現在已經沒印象了
留言也是說沒辦法自動準確transcription扒譜
所以沒做扒譜功能
(其實他每個時間點的音高已經做出來了,只是沒有轉成音樂檔或文字檔記錄下來)
那我想做的就是這個
當然我做的肯定也是不準的
(目前還在想要怎麼做?)

在一番努力(誤打誤撞)之後總算有初步成果
雖然目前感覺只能錄到雜訊
出來的效果跟想像中的差很多
目前算是處於根本不能用的狀態
我試著唱歌跟喊話感覺效果也不是很好
是有些想直接分析檔案看會不會好些
至少現成的音訊檔大多有去躁處理
可是我大概覺得就算用音訊檔也不會好到哪邊去
因為我目前擷取頻率的方式是
在一段時間中,選取頻率最高的
因此試著錄了幾次,就算不說話也會是高音雜訊
而現成的音訊檔許多和聲,最高的頻率估計不會很低,大概也會是一堆雜訊吧
看樣子沒那麼容易
可能還是要老實從pitch detection的原始碼下手

雖然沒什麼成果
但至少產生.ogg檔沒問題(.wav還不清楚要用什麼codec,.ogg網路有看到範例就直接用了)
就先貼上來吧
-----------------------10/19↓---------------------------------
嗯,嘗試了一陣子
在能錄音、顯示頻率資料(WebAudio的analyser.getByteFrequencyData(dataArray);)之後
突然覺得下步有些茫然
繼續找資料

這方面的英文是pitch detection(音高偵測)
但實作方式我沒看到用getByteFrequencyData()來做的

有關getByteFrequencyData()總算找到個比較有用的了
簡單的來說
getByteFrequencyData()的值,都介於0~255之間
那0~255的話,是代表幾Hz頻率呢?
要看fft的窗格大小,也就是analyser.fftSize = 2048;這樣的
若沒寫,預設是2048
假如fftSize是2048的話
那getByteFrequencyData(Uint8陣列);
會得到個1024大小的Uint8陣列(也就是fftSize/2大小的陣列)
那取樣率要知道是多少!!
如果是預設44100Hz的話
44100(取樣率) / 2048(fftSize) = 21
因此0代表0,1代表21Hz,255代表5355Hz

附帶一提
(自己的麥克風取樣率在這看
)

嗯,知道這些之後...我看我配合震盪器寫不寫得出來
寫得出來還要看效果好不好
但若效果不好,其實我是不知道怎麼改良的

----------------------

找到個比起MIDI檔轉成WAV檔再重新組合更好的做法
直接用Web Audio的震盪器
詳情請看
更改頻率與播放時間可用
const G4 = 440 * Math.pow(2, -2/12);
var t = audioCtx.currentTime;
osc.frequency.setValueAtTime(G4, t);
可參考這篇
雖然出來的聲音音量很穩定
(可視為缺點也可視為優點,不過音量穩定的話,若不滿意只要自己找方法淡入淡出即可
自己演奏的話倒很可能同個音沒辦法長時間發那麼穩定)

麻煩了,不知道是被擋掉還是出錯的程式片段是
ole.CoInitializeEx(0, ole.COINIT_APARTMENTTHREADED);
這樣就很難救了
go-ole是別人寫好的函式庫,還蠻龐大的
試著
fmt.Println("err")
fmt.Println(err)
有顯示字串(程式確實在這邊終止),但沒有顯示錯誤內容,很有可能是被擋掉了吧!!
那這計劃應該是宣告失敗了
改個目標

昨天想了一下,昨天的目標意義不大
因為在執行錄音程式 -o 檔名.wav時
就會產生對應的檔名.wav
因此若要做對網頁有用的程式
就勢必得用WASM一類的技術
不然程式還是全都得放在客戶端
那昨天研究了一陣子Go語言寫WASM
推薦看這三篇
Go語言如何編譯成WASM與實際運作
(在Windows底下,Go語言編譯成WASM用的是
set goos=js
set goarch=wasm
較麻煩的是以後若編譯正常程式時,還要把goos跟goarch手動切回來
以我的例子是
正常編譯是
set goos=windows
set goarch=amd64)
如何使用Javascript呼叫Go語言副程式
如何傳參數

我測了一下之後
就算有設參數
應該是寫檔案的程式會被擋掉
會有個Warning,然後
exit code: 1
我查了下,不知道exit code所代表的含意
只知道exit code若是不等於0的話
就是程式不正常的結束

因此要把
這裡面的main.go程式碼
改寫成WASM可以接受的形式了
那今天主要就是
找出哪段程式碼要改跟要怎麼改
我比較擔心的是,最核心的獲取電腦所播放的聲音這本身被擋掉

-----------------------10/18↓---------------------------------
我實在是太在意網頁錄音的可行性了
查了一堆資料,沒找到有用的
頂多只找到有相同問題,但沒解答的
但看到Stackoverlow上有個有趣的提問底下的互動
「Do you mean ...」
忘記英文原文,意思大致上是,你的意思是用Javascript還是Node.js
嗯,後來我想了下,純網頁應該是很難辦到,但若配合伺服端程式語言使用的話
那應該是很有機會的
因此稍微找了下現成的軟體用的錄音技術大概是怎麼辦到的
後來找到
Audacity這套軟體,是用WASAPI來達到把電腦所有音效錄下來的效果
那WASAPI應該是個關鍵字
我再配合我要用的語言應該就找得到
然後我就找到了這篇!!
"GoからWindows Core audio API使えるようにバインディングを書いた"
哦,太棒了,有Github,README.md也寫得很好
照著用測試了下,還真的可以錄下所有電腦聽得到的音效(不管有沒有麥克風都行)
那我覺得應該是有機會做到
"把電腦上的所有聲音(含麥克風與不含麥克風都有)錄起來
然後轉成對應的音階,用成MIDI的聲音類型(但檔案格式是.wav)"

因為Go語言可以利用強者 Yoshiyuki Koyanagi所提供的程式,產生出WAV檔
那我們只要把產生出的WAV檔
用像Web Audio這樣的Javascript內建程式庫(其實不算內建,不過有些主流瀏覽器支援)
就可以做傅立葉轉換
而且是快速傅立葉轉換
或者說要是沒快速傅立葉轉換,就不會廣為被工程所使用了
把複雜的不規則波形轉成一個個音階的單獨波形
(有波性質的都可以用傅立葉轉換來處理,不只有聲音,只是聲音的應用比較直覺)
也就變得像Sin、Cos那樣的波
而知道波的頻率就相當於知道波的音階
最難寫的快速傅立葉轉換已經有人做好了
因此剩下的程式應該都是較不需要動腦,純費工的程式
這樣做出來的可能性就大幅提高

不過...
若一定要配合伺服端語言的話
手機就不能單獨運作寫出來的程式了
(我不清楚手機要怎麼當Server,應該也不太適合當Server)
而這功能
因為有Now.in該網站的前車之鑑
(Now.in是個線上廣播電台
雖然該平台本身不提供音樂
但線上點歌的,大多用的音樂是未經授權的
因此隨著後來Now.in越來越受歡迎
開發者因為家人人身安全受威脅
被逼得刪除掉自己苦心經營的網站
在Now.in被查封以前
我還有看過Now.in網站開發者維護網頁安全
分享怎麼發現被DDOS攻擊與解決的經過的文章
感覺是很認真在經營網站的開發者)

總之,也不適合租伺服器來做這功能
因為錄下電腦所有音效這功能,不是用來錄歌,就是用來錄自己唱的歌
那絕大多數的使用情形肯定不是原創的
很容易有法律爭議導致被找麻煩
因此我就純粹做著自娛自樂
若做得順利的話開放原始碼
但拿去用會不會出問題我就不知道了
我也不知道Yoshiyuki Koyanagi跟Web Audio它們的程式使用上是否有什麼限制
像是程式碼授權、是否允許商業目的使用這樣
就僅是提醒下

雖然說剩下來的程式應該需要動腦的成份較低
但還是要花些時間的
我就先去想程式接下來要怎麼寫
我想10/18的目標
網頁檔上按個按鈕
然後Go語言啟動Yoshiyuki Koyanagi所寫的LoopbackCaptureSharedTimerDriven.exe
然後再按個按鈕結束錄音
Go語言再對執行中LoopbackCaptureSharedTimerDriven.exe送中斷訊號(Ctrl-C)
接著再讀取WAV檔案給使用者下載
先做到這樣就好!!

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
附帶一提:若真的是用我上述寫的方法
應該是想因為做網站被抓去關
這樣拿到鐵飯碗(吃牢飯過一生)的如意算盤都打不響
那不管有沒有租伺服器
使用者都必須給自行當http伺服器才能用(我的做法是用Go語言,覺得這樣較省事)
不然由伺服器執行LoopbackCaptureSharedTimerDriven.exe
錄的也肯定是伺服器本身的音效
因此...嗯,好吧
最理想的狀況是純網頁
但純網頁很可能是權限問題(安全性考量),因此應該沒辦法直接呼叫些WinAPI來做到這效果
我目前是想不太到有什麼好方法來處理!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

不過我10/18有些事情
且現在已經12:05了
今天應該是蠻有可能做不出來的
因此這雖然是10/18的目標
但這應該也是10/19的目標!!
只是10/19要是提早完成的話
就可以提前進入最終目標
把儲存的錄音檔,轉成音階,用MIDI轉出的.wav檔,組合成新的.wav檔
這樣就能達到 簡易去人聲軟體(理論上用麥克風唱也是可以啦,就把歌曲轉純音樂) 的效果了

----------------------------↓10/17------------------------------
昨天(10/16)我其實是在研究,如何用Javascript檔錄音
但是getUserMedia()不能同時錄麥克風跟電腦的音效
或者說是HTML5底下,還不知道能否不透過麥克風來錄電腦的音效
(唔,理論上用立體聲混音,捨棄麥克風的聲音的話,應該是能錄電腦的音效,但我沒實際測試過)

於是今天我又重看了.wav檔格式
覺得"把midi.html的聲音製作成.wav檔,透過Javascript寫.wav二進位資料達成"
這個短期計劃還算合理
10/17,目標是,把原始的wav檔,變為播放時間兩倍長的wav檔(同樣的內容播兩遍)
先不用程式的方法實現
僅使用PSPad等有提供十六進位編輯器的做法直接改.wav檔內容來完成
(其實這段我在2017/11/24左右有研究過,但是那段時間精神不是很正常就是了)

現在根據維基百科連結
其中的內容
覺得要改什麼具體清晰很多!!

--------------10/17,修改.wav檔成功-------------------
基本上在取樣率、取樣頻道...全不變的狀況下
只要改這兩個橘色框框就好

然後在綠色框框處後面複製資料,貼上兩次即可

橘色框框處要改多少要看原檔案內容
像我這個原檔案是

3EBB0600
意思是在這後面的內容長度是6BB3E個bytes
F8BA0600
意思是data大小是6F8BA個bytes

讀起來比較不直覺是因為採用的endian(位元組順序)是little endian,所以要由右至左讀

所以我們可以很清楚的知道,第一個檔案有6BB45個位元組
(6BB3E+7=6BB45)
而修改後兩倍大小的檔案則是D367D個位元組
(根據圖檔,3676 0D00,也就是000D3676 + 7 = D367D)
上述檔案具有幾位元組
可以在十六進位編輯器中,按ctrl-end(迅速跳到檔案尾端的快速鍵),來驗證下想法

.wav檔基本上沒有經過壓縮
因此檔案格式很好理解
(雖然其實有損壓縮的格式其實也長得類似這樣
像影片檔.mp4,就是用一堆mdat這樣子的標籤接上這區塊大小的內容所組成的
不這麼做程式不知道一次要讀幾位元組才算結束
.wav單純的原因是
它的音訊檔實際音訊內容所佔的大小也很好算
雖然我目前還不會算
應該就是 每秒取樣幾次*所使用的頻道數量*取樣一次用幾個bytes這樣

.mp3因為會把超過人耳能感受到的頻率截掉
雖然我也不清楚細節
或者說我根本就不知道.mp3檔的檔案格式長怎樣
但我猜其檔案大小就沒.wav檔那麼好估算)

------------------------------------------------------------------

老實說我是很想做個網頁程式
能夠把電腦上的所有聲音(含麥克風與不含麥克風都有)錄起來
然後轉成對應的音階,用成MIDI的聲音類型(但檔案格式是.wav)這樣
不過這個目標目前太過宏大
先從簡單的做起吧!!
我這幾天比較有空,若目標訂小點應該是有機會做出來!!
至於如何取得網頁瀏覽者的電腦音效內容
這個根本就不知道要用什麼函式來處理的
就先擺在後面,也許哪天網路出現相關文章或技術是在處理這件事情的
但在找到相關資訊前
我想"透過網頁錄電腦上的所有聲音"
目前對我來說是無解
引用網址:https://home.gamer.com.tw/TrackBack.php?sn=4164889
All rights reserved. 版權所有,保留一切權利

相關創作

留言共 0 篇留言

我要留言提醒:您尚未登入,請先登入再留言

2喜歡★y541258 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:10/15,midi.h... 後一篇:10/20,思考下一步與...

追蹤私訊切換新版閱覽

作品資料夾

sakima55詐騙季來囉?
晚上公司老闆說帳號被限額5萬,這麼晚了沒打電話傳訊息感覺詐騙,在知道對方限額是10萬下直接無視。看更多我要大聲說昨天22:42


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】