2010-11-09 94 views
0

我創建了一些基於傳遞的音符和八度音程生成MIDI文件的JavaScript代碼。大多數情況下它工作得很好。問題是C音符(音符= 0)比任何其他音符(1(C#)到11(B))都短得多。生成的midi音符長度

這裏是我的代碼:

function play(note, octave, program){ 
    var note = (octave*12 + note).toString(16); 
    var velocity = 'ff'; 
    var MIDI_DATA = 
     'MThd%00%00%00%06%00%01%00%01%00%C0' + // midi header 
     'MTrk%00%00%00%0E' + // track header 
     '%00%C0%'+program+ 
     '%00%90%'+note+'%'+velocity+ 
     '%70%30%00' + 
     '%00%FF%2F%00'; 

    MIDI_DATA = btoa(unescape(MIDI_DATA)); 
    var e = document.createElement('embed'); 
    e.src = "data:audio/mid;base64,"+MIDI_DATA; 
    e.type = "video/quicktime"; 
    document.body.appendChild(e); 
    return e; 
} 

爲什麼C音符 - 打(0,4, '18')的聲音比任何其他短得多 - 打(1,4, '18') ? 音調似乎是正確的,只是音符的播放長度。

我認爲這可能與C值爲0有關,但我不知道我在這裏用MIDI來做什麼來發現問題。

注意:此代碼在IE(任何版本)中不起作用。

+0

當你調用MIDI會發生什麼直接在瀏覽器/ quicktime文件不使用嵌入標籤?它玩的時間長度是否正確? – epascarello 2010-11-09 00:44:33

+1

我無法重現這種行爲 - 所有音符都播放相同的時間。更新你的QT版本? – LesterDove 2010-11-09 01:17:26

+0

這似乎是我的聲卡問題。我在多種操作系統/瀏覽器組合上測試過,但不是多臺電腦。感謝您將此引起我的注意。我應該先檢查一下。 – marshallpenguin 2010-11-09 01:34:06

回答

1

如果我沒記錯的話,MIDI音符用1到127之間給人一種音調和速度(即響度)出場,並用0

+0

你是對的,127以上的代碼是控制代碼,而不是數據。速度應該是'7f'而不是'ff'。 – Guffa 2010-11-09 01:07:18

+0

將它從ff更改爲7f沒有任何效果。但是,謝謝。 – marshallpenguin 2010-11-09 01:15:56

0

當音符的速度給予同樣的間距停止值小於16,您將以無效的轉義序列結束,即%0而不是%00unescape函數不會將其轉換爲字符,但保持不變。由於它是兩個字符而不是一個字符,它會溢出到速度字節中,而其餘的MIDI代碼不會同步。

您可以使用這樣的代碼,以數字格式爲兩個十六進制數字:

function toHex(n) { 
    var code = '0' + n.toString(16); 
    return code.substr(code.length - 2, 2); 
} 

用它做的音符值兩個數字:

var note = toHex(octave*12 + note); 
+0

感謝Guffa,但您提供的代碼不會改變任何內容。我忘了提及,截止時間只發生在四度八度。 – marshallpenguin 2010-11-09 01:11:21

+0

當音符的十六進制值爲'30'時,音符切斷。 – marshallpenguin 2010-11-09 01:18:38