AWK产生新领域

时间:2018-08-04 17:11:18

标签: awk midi

一个MIDI数据集显示其时间线,音符开/关,香奈尔编号,音高和力度。

0 On ch=1 n=64 v=65
240 On ch=1 n=76 v=68
318 On ch=1 n=80 v=68
397 On ch=1 n=83 v=68
480 Off ch=1 n=64 v=0
480 Off ch=1 n=76 v=0
480 Off ch=1 n=83 v=0

查找第一个字段的增量时间效果很好

$ awk  '{print  $0-p}{p=$0}{print p }' sample

0
240
78
79
83
0
0

我要寻找的是“ On n = x”和下一个音符“ Off n = x”之间的字段$ 4之差。这将成为注释“ On n = x”行上的字段$ 6。例如,“ 0 On ch = 1 n = 64 v = 65”和“ 480 Off ch = 1 n = 64 v = 0”的deltatime($ 1)给出了n = 64的持续时间“ 0 On ch = 1 n = 64 v = 65” 64 v = 65 dur = 480“。

0 On ch=1 n=64 v=65
240 On ch=1 n=76 v=68
318 On ch=1 n=80 v=68
397 On ch=1 n=83 v=68
480 Off ch=1 n=64 v=0
480 Off ch=1 n=76 v=0

将成为

0 On ch=1 n=64 v=65 dur=480
240 On ch=1 n=76 v=68 dur=240
318 On ch=1 n=80 v=68 dur=not clear yet because no Off in sight
397 On ch=1 n=83 v=68 dur=83
480 Off ch=1 n=64 v=0 dur=not clear yet because no Off in sight
480 Off ch=1 n=76 v=0 durf=not clear yet because no Off in sight
480 Off ch=1 n=83 v=0 dur=not clear yet because no Off in sight

样品更新

0 On ch=1 n=64 v=65
240 On ch=1 n=76 v=68
318 On ch=1 n=80 v=68
397 On ch=1 n=83 v=68
480 Off ch=1 n=64 v=0
480 Off ch=1 n=76 v=0
480 Off ch=1 n=83 v=0
480 On ch=1 n=66 v=88
481 Off ch=1 n=80 v=0
720 On ch=1 n=71 v=68
780 On ch=1 n=76 v=68
840 On ch=1 n=81 v=68
900 On ch=1 n=83 v=68
960 Off ch=1 n=66 v=0
960 Off ch=1 n=71 v=0
960 Off ch=1 n=76 v=0
960 Off ch=1 n=81 v=0
960 Off ch=1 n=83 v=0
960 On ch=1 n=59 v=69

将成为

0 On ch=1 n=64 v=65 dur=480
240 On ch=1 n=76 v=68 dur=240
318 On ch=1 n=80 v=68 dur=163
397 On ch=1 n=83 v=68 dur=83
480 On ch=1 n=66 v=88 dur=480
720 On ch=1 n=71 v=68 dur=240
780 On ch=1 n=76 v=68 dur=180
840 On ch=1 n=81 v=68 dur=120
900 On ch=1 n=83 v=68 dur=160

1 个答案:

答案 0 :(得分:0)

我不明白为什么您希望您发布的内容成为预期的输出。为什么要报告没有持续时间,因为当第二个字段为“关”并且您已经报告了该音高的持续时间时,还没有看到“ Off”?

所以这是我认为您可能确实想要的东西,如果不是,那么希望您可以按摩它以做您想要的事情:

$ cat tst.awk
{
    time  = $1
    state = $2
    pitch = $4
}
!seen[pitch]++ {
    preDur[++numPitches] = $0
    pitches[numPitches]  = pitch
}
{
    stateTime[pitch,state] = time
}
END {
    for (pitchNr=1; pitchNr<=numPitches; pitchNr++) {
        pitch = pitches[pitchNr]
        dur   = ( (pitch,"Off") in stateTime ? stateTime[pitch,"Off"] - stateTime[pitch,"On"] : "not clear yet because no Off in sight" )
        print preDur[pitchNr], "dur="dur
    }
}

$ awk -f tst.awk file
0 On ch=1 n=64 v=65 dur=480
240 On ch=1 n=76 v=68 dur=240
318 On ch=1 n=80 v=68 dur=not clear yet because no Off in sight
397 On ch=1 n=83 v=68 dur=83