1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ADX2ロボット機能でMIDI4オクターブに挑戦

Last updated at Posted at 2021-02-03

#はじめに
MIDIで取り込んでみたけど、オクターブの範囲が広い場合、設定範囲の上限、下限にひっかかってしまう。

そこで、それを回避するようにしてみた。

まず、トラックを分け、トラック側でベースのピッチを変更したものを用意する。
image.png

それでも足りなかったので、高い方にオートメーションでさらにオクターブ上を追加。
image.png

###ピッチ上げすぎ

このまま再生を試みる。
すると、再生ピッチが高すぎて再生時にエラーがでる
image.png

サンプリングレートはオクターブが上がると倍になる。
もし44100の再生音をオクターブ上で再生しようとすると88200になる。
3オクターブ上だとさらに倍の176400になる。
4オクターブ上だとさらに倍の352800
と、かなり危険な値(流量的に)になるので、
元のレートを半分にすることで上がりすぎないようにした。
元の波形のレートを下げるのは簡単で、マテリアル>エンコード>リサンプリングレートを下げればよい。
音は若干劣化してしまう。(ちょっと古いサンプラーみたいなLoFi感)
image.png

他にもいろいろ鳴っていれば問題ないかも。
音色にもよる。 例えば声とかだとフォルマントも変化してしまうので、いかにもサンプラーみたいになる。 木琴のようなものの場合は大きさも変わるから不自然にならないなど。
この動画のエレピの場合は、若干長さの変化が気になるところかもしれない。

スクリプト(4オクターブ対応版)

readMidi4oct.py
# --Description:[tatmos]MIDIを読みこみwaveformを配置する
import sys
import cri.atomcraft.project
import cri.atomcraft.project as acproject
import cri.atomcraft.debug as acdebug
# --BeginUserVariable
"""
MIDI_FILE:
  type:string
  comment:MIDI File Path
MATERIAL:
  type:object
  comment:Material
"""
MIDI_FILE = "C:/Users/tanakat/Documents/Nuendo/20210128GGJ/20210128GGJ.mid"
MATERIAL = cri.atomcraft.project.get_object_from_path("/WorkUnits/WorkUnit_Block_IntaractiveMusic_MaterialInfo/MaterialRootFolder/Sozai20120527/epianoC.wav")["data"]
# --EndUserVariable

# 選択しているCueを得る
selected_Cue = acproject.get_selected_objects("Cue")["data"]
if not selected_Cue :
    acdebug.warning("MIDIを読み込むキューを選択してください。")
    sys.exit()

# オブジェクトパス表示
acdebug.log("Target Path:\"{0}\"".format(acproject.get_object_path(selected_Cue[0])["data"] ))

# Materialを得る
if not MATERIAL :
    acdebug.warning("Materialをセットしてください。")
    sys.exit()

#Octabe2のトラックを用意
track2 = acproject.create_object(selected_Cue[0],"Track","track2")["data"]
acproject.set_value(track2, "Pitch", 1200)
automation = acproject.create_automation(track2,"Pitch")["data"]
acproject.create_automation_point(automation,0,1200)
#Octabe1のトラックを用意
track1 = acproject.create_object(selected_Cue[0],"Track","Track1")["data"]
acproject.set_value(track1, "Pitch", 1200)	
#Octave0のトラックを用意
track0 = acproject.create_object(selected_Cue[0],"Track","Track0")["data"]
#Octave-1のトラックを用意
trackm1 = acproject.create_object(selected_Cue[0],"Track","trackm1")["data"]
acproject.set_value(trackm1, "Pitch", -1200)	

# MIDI読み込み
import mido 
from mido import MidiFile

mid = MidiFile(MIDI_FILE)

def setWaveformRegionParam(waveform_region,msg,absolute_time):
    acproject.set_value(waveform_region, "Volume", msg.velocity/127)
    acproject.set_value(waveform_region, "DelayTimeMS", absolute_time)
    acproject.set_value(waveform_region, "Comment", "note {0} vel {1} absTime {2}".format(msg.note,msg.velocity,absolute_time))

for i, track in enumerate(mid.tracks):
    print('Track {}: {}'.format(i, track.name))
    absolute_time = 0
    for msg in track:
        if msg.type == 'set_tempo':
            tempo = msg.tempo
            acdebug.warning("temo is {0}".format(tempo))
        if msg.time > 0:
            absolute_time = absolute_time + mido.tick2second(msg.time,480,tempo)*1000

	#note onのみ
        if msg.type == 'note_on':
	        print(absolute_time)
	       
	        # マテリアルを指定してウェーブフォーム リージョンを作成
	        if (msg.note-60) > 24:
                    #基準から1oct上の場合トラックを分ける
                    waveform_region = acproject.create_waveform_region(track2, MATERIAL)["data"]
                    acproject.set_value(waveform_region, "Pitch", ((msg.note-60-24)%12)*100)	
	        elif (msg.note-60) > 12 and (msg.note-60) <= 24:
                    #基準から1oct上の場合トラックを分ける
                    waveform_region = acproject.create_waveform_region(track1, MATERIAL)["data"]
                    acproject.set_value(waveform_region, "Pitch", ((msg.note-60-12))*100)
	        elif (msg.note-60) <= 12 and (msg.note-60) >= -12:
                    waveform_region = acproject.create_waveform_region(track0, MATERIAL)["data"]
                    acproject.set_value(waveform_region, "Pitch", (msg.note-60)*100)
	        elif (msg.note-60) >= -24 and (msg.note-60) < -12:
                    #基準から1oct下の場合トラックを分ける
                    waveform_region = acproject.create_waveform_region(trackm1, MATERIAL)["data"]
                    acproject.set_value(waveform_region, "Pitch", ((msg.note-60+12))*100)
	        else:
                    #基準から上下離れている時
                    waveform_region = acproject.create_waveform_region(trackm1, MATERIAL)["data"]
                    acproject.set_value(waveform_region, "Pitch", ((msg.note-60+12)%12)*100)	
	        setWaveformRegionParam(waveform_region,msg,absolute_time)

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?