Node for Max 上で tonal ライブラリを利用して Key Scaler を試作 #max8 #n4m

Midi NoteのPitchを特定のスケールに矯正

cycling’74のN4Mサンプルにも入っていた tonal をnode objectで使ってみたのでメモです。

鍵盤の音を特定のスケール(とりあえずC Major)に矯正するスクリプトとなっております。Node for Maxのご参考にどうぞ。

tonal.js

引用 “tonal is a music theory library. Contains functions to manipulate tonal elements of music (note, intervals, chords, scales, modes, keys). It deals with abstractions (not actual music or sound).

tonal is implemented in Typescript and published as a collection of Javascript npm packages.

It uses a functional programing style: all functions are pure, there is no data mutation, and entities are represented by data structures instead of objects.”

https://github.com/tonaljs/tonal ※導入方法はこちら参照

keyscaler.js


const MAX_API = require("max-api");
const { Scale } = require("@tonaljs/tonal");
const { Key } = require("@tonaljs/tonal");
const { Mode } = require("@tonaljs/tonal");
const { Midi } = require("@tonaljs/tonal");
const { Note } = require("@tonaljs/tonal");
const { Chord } = require("@tonaljs/tonal");

const notes = Scale.get("C major").notes;
console.log("notes:"+notes);

let midiNotes = notes.map((value) => {
    return Note.midi(value+"0")
});
console.log("midiNotes:"+midiNotes);

const handlers = {
    "getScaledPitch" : (pitch) => {

        let returnPitch = pitch;

        while(
            midiNotes.every(value => {
                return ((value % 12) != (returnPitch % 12))
            })   
        ){
            returnPitch++;            
        };

        //MAX_API.post(pitch + "->" + returnPitch);

        MAX_API.outlet(returnPitch);  
    },
    /*
    [maxAPI.MESSAGE_TYPES.BANG] : () =>{
        console.log("bang");
    },
    */
};

MAX_API.addHandlers(handlers);

jit.gl.gridshape の matrixoutput についてのメモ #max8

このような音に反応するPatchをつくる際に、jit.gl.gridshape のアトリビュートに対して @matrixoutput 1 として、3Dデータを行列に分解して出力するのですが、その時に出力される matrix が 12 plane あります(多い)。planeにはvertexやnormalなどの行列が入ってるはずですが、それぞれの意味する所・種類がわからないと適切な処理ができません。

Reference や Help などを読んでもイマイチ何を指しているかわからなかったので調べました

matrixoutput

上の画像の通りです。11番目のplaneは謎でした。とりあえず触って楽しいのはvertexかcolorくらいでしょうか。

おまけ:音に反応させるpatch

動作デモ

上で調べた結果から、vertexに対して波形を掛ける事で動かしています。CPU上で擬似的に行うvertex shaderといった感じです。

追記

サンプリングした波形の値が両端で揃っていないので、円形にマッピングした場合にアーティファクト(ずれ)が出てしまいます。

右下がアーティファクト

そこを良い感じに補完というか誤魔化す処理をgenで書いてみました。

波形を反転して、x = 1 付近では反転した波形を利用し繋げる
変なアーティファクトは無くなりました

Max Patch


----------begin_max5_patcher----------
2793.3oc6c0riiiaD9r6mBAebSuMDIEojBPR5ja4bNNXggZa01Zhrjfjb28r
K1AY2q6sEHmxsMGywbNOMC1.j2hPQRYKYqennMksFLXlo+gTVrpupXwhjUUy
2c2r4OE+le1bieqw6LlM66ta1LVSEMLS76ylu06skgdYrGa9x3sa8ixmeOuu
b+2xYs+mix8SShC8xChiJ6MXEqu3md+WCgkMl3kubSPz5Eo9Ky4CM1x8Ay6M
rA1EeCfMK9Fj9UiuQ7gh1sMHJzOmQDfCMFuKurUyhF+96tq3K2KI2D4+Jk3N
gYBi8V8jWz5xN3iR9GR74z6bVm6ItJrIvoC1z1zhyXL9C6v9E3v3RvkiKeeP
9Cq8iZkIo8uXqWdZvayu2XdyrKnC1kf.UjpV.UXWX0WuepfIEb4r4OGD5+he
ZVgN2g2wr4dIIUZdVkORAz79X1Kx498MEDwaBsuoT+WBN90ReuoTlLmxg6RY
nz72HVyO7ZhW4mFsKXubhIjDjDSbD4s0OKwaoeCBfhwbOzQXpH.S17B.fP3+
J19.7Qk5qCiW9W8YhCyxFiS7iBhRR8ynSS4yFq18J+m81Elu343n7rfukQH.
pPoo9eVPnM1YAqv3h+XZfW3ddXcZvp3nBhnl.on4xg6czY3744UYF1SD4kzv
GlpoQQlV5Lixj6xdxKsPd8TneEsFptdbbX8t1+4B8eNWzcRPTzQnXdbR6clF
rdSGe1mhoctsq2MqmrE6h38tfpZjuHy6k5nctWXnXpa8W+adQAzIl94AbQ.0
fRYm9QdTFcS1xz3vvZ7KumWZnmUTU8k9uFrJeCafppLPe7fjRkn46kxqBV6m
kWusbu0Y0aIK+CbPuRS6dRLUdQt+1D5xEG8.zIIAY4YaheMS7fkJZUAfCqYU
cpcU6f0ZuK6g0sItsvX2g1Owl3dqfmXIzs5mqo03L4VAYlAsLO1X3oFDQ063
30.lUtNfvLykGKRhe0.oHZ3zCZ.sXl.Pb6bV18CGfqMb7UFeMPQzvrGz.A39
BH7OXJfFYuF7sFePM7nuoJHwxcHTyNNbqBGJZ5voWsCvTCNntSsUMvvVNvvV
X9nerv7ZiEu3uzvzvTM3fzGbv8PDZQj0NJ7pqa36kV37fR3AtG7.3xTOP.95
JtS.7HHxP00UjxkC9TEnyDXpBcDqiEUXVK47uhKxQ3ywHoYCb6gMpDFD0l6m
Lxpn+lggr3coKKkpBK+F0oPpG24AQ62116N3N0QOXb5J91gkSzLTJCHMoQWL
2.Z7M5gJbkjJr3OmdHhgfDipPBODJCbkgGb6nioVHLx.HLsANlRRDDMp.K8T
YywVD4N.zQWhHaIoA2wFbjkvF3ZCBXj2x.OH41N7e1AYF9.6H713k3a7oe7m
+u+6e4W+O+xm9g+0+6u8O+0e5u+oef92+wm9wepg6F.r+tApdpjVNkGDUiN5
Yxbnwg42qCjs0HhUkCWt9YT9Dcs83Hi+hWTlweJNb0b8duBOGFSeIGNa7TJg
j6mtfeHbU70hRloa8X7Dosygu3z2a8BGr63.3cfhCahARXSkN.9K3spDrM3i
sdaCYAqi7BajGQt8eoJXt9.xZrtTkBc9mSxVuKnpx6QGYdyBylYRmllDb3n4
aj2sYRVW9l.cLKc8skIAUNndcI5kCUJtnjJGw4PPI6giRN1L3gXadqfRLiAs
OUfZ8nvjPSrOoqYBbkeLoBeBP2JyDJk4VCWlaovLCW7MlLuEihoF6RVUbKHs
BKMBInNu2Ul9NluweLpaKhl59ZlyLVk58ZCK6i5Jj.rgLp2w1husdULqadIY
h5hoprQW2AtsqaE1.iGK1nXNYxqAQqhe8bteeHo+UdsK3GpkFB7ALk4.UXtr
ODs7H9ZDmZUfAKKH6OdVPPyq3f5z5CGYHPqR2Ro.C5ZZ8wKOOsa6yc4jpbFk
1qqTLXb2fKdkLHavPnCBxgPP0PB5LvvUAYIgdenbYnK2xeiAz5bBzx3CUQUr
K5BgpmO7oruPPq48t9OxAMt9Bs1KH5iyUQtK1+SqlgP8aIFYxsDyitfhqDpa
1c6tv7fka7hh7CewiJqixa2i.Ur5jGudcnuRvQPTKRcfDAXmXWf6+5UJ.67V
sr286dem67Ez8Ne4tSPZ4JOtM1i2v82GPFt+9.De6+t12396eIB5R77dOWLD
VpftD9kftrRLIg3ygvrSdjZFUD2ElDyuD0keIpK+RTWddQcY8KOntUw+vb0B
MJaWQD06V4nNLub25uFhwgeihABDruHeQ3LuMGDbYaF+1NxW9JEgBTePA2.N
D3NYfBE0Jv8EtbtbkBhym6JE39hTNGgNg0zAITNfi6Sq.XZIxuD6IS.G+6+c
pFCk8YtvkXyuq.liynoQzFS4B0Pi9VGw0gmyQH9FHfSjDU.9fhKlXI4bEt5w
oWDwMn5QRwynlUz9huVWwIGR.Mea62fnQPjATMzvpWKGN3RONukhv1t7ztHx
7Orww1hAg1yLC98ohtsb2tKFl9CKiiSW0FKa2alJIbbfowKbj5FmmWFGFm1F
C22B.XwsTZwioJ7TfgewOk9ysvwPGoBcbfHsrmBahjktQ.E8ND12RdhvoSrq
ZKmoR9WATzAQXe14INtUlRHSVkba.HtJhG8YhfvS2nR7.NUvCGEwi9RzFB+h
2lb3gsh3Qe4yJluXoCbZAGDMk52V78NL0fCrlx8aK94xM0fCKEgCa47otb01
ICdnZoAn+TZ0ZRhGJtISP+ozJrh6oSG7P0jZ0RtK5XxgGZJCvEW3+TBNDYDe
S+QSYEdYPQP36gWhpuB3y37BGTKWY9bOwvEbqUoNvjHyvkNois5H6+Lut4Cc
GY7q60kxHsSYNWWJytcJy95RYcjloja17tGeUoLXGITs00kx.sSYnqKkAamx
fWWJCM5EgCYoLqwN2zACqrFzHjoILCOfx9f1paICo1SfzEQXO.hvRWDgy.HB
70tLxTPDDMQDPyAPD15hHFR0ZwQWDAb.DgqtHBzPJOL5pzrzfk6NnBcUBTrj
EKHi9BM3afB.kzvyn6ffrDFTinCwZ.DAXLQGooL6a0R6CTi9nHsQXrNUdj1x
iNUgwR6tlsNoBYs0w.MvnZEVZmpIi9djrFBpMpjFYHfF3ljxrGaMM4Emvwlz
HvafBJH1dXkawKbAfS6o9qoJo9KnRxueqm5ugOrwKZUnuwid6xiWjFm6k6u+
tMF.T0UR.C4EFaQR.Cv3qbkeSv4a8y1H3aVDploBei5O4msrEUjldJ8QtiAe
+ZbZ3JiG4IBJ0tvirJZAktK94BMbCL.V7OISIb9+uD0VUhnyxE.O1s4+2wCD
6phRA5hqTbnnQ9HmIoiVRw08Y73pfsT5jT7uyJe46WiARNGP47KHOmeEhw8j
JDCCTkf04I5CruIK5pf4b9rN.0Y0wo85lnHt7.pUYLuIXc6SX8MAgA49KplB
.csDA7RAArOW8q.miHG6hi.W54nh64hqZD6kcjpe1escXN0Nz3i7HW4gt9gx
2uuaJOPXYXwKv3.FBVddiDPhQBTw4a00OjQHcD4T+5SUmIkYjMadjM0+Hi0x
bBYzUqekZWLld.SStvLsqLV6tDyPqsQ41XQfNPWoFYXyiLT+iriNjqPolG4N
VqhU+BltXBVYLPBIZQxJyPirzhnUpg1VG.NRJYs8EPqB4NfQ5xhuRMzHsrN.
YrfWmwZfjAKO0WZtS7GUH2JFhiJfaGU71Nsvs0dQa63B1FqXs0TgZqXmT288
28+gE.Z1C
-----------end_max5_patcher-----------

jit.gl.pix で簡易モーションブラー #max8 #jitter

おなじみバスケットボール

単に1フレーム前の画像と今の画像をブレンディングしてるだけです。

なぜかjit.gl.textureとzl regを通すと1フレーム前の映像がjit.gl.pixに戻るので簡易ブラーが実現できます。流れている線をみても特にtexture番号が変わっている訳でも無いのに不思議・・・内部処理に何か依存してるんでしょう。

ディレイは?

ディレイをしたい場合は、jit.gl.texturesetでやりましょう。

jit.gl.texturesetのhelp

jit.gl.pix で Gold Noise #max8 #jitter

リアルタイムグラフィックスの数学を1日1サンプルずつ進めているのですが、ノイズ生成の章でGenには無いビット演算を使っていて困りました。

別のアルゴリズムを探してみようと思い、出会ったのがGold Noiseです。少数の精度が低くても使えると書いてありました。名前がカッコイイ・・・

Gif

Blog容量の問題でフレームレート解像度は下がってますが、辺なパターンもなく良い感じでした

code


----------begin_max5_patcher----------
705.3ocwW10aZCCEF95vuBKeYGE4ORBI6evtaec2TUUJ3QCJwA43vXpp+2m+
HzMlnkyvQdHAV1wgW+jWe74jmlkfen6fnGidO5anjjmlkj3FxNPxX+Dba0gU
MU8togkhez8vV7b+kzhCZ2verRU0h5Eh0Hdd1wKKGZ6FzMBs6doiiVu1cKl+
la4uLU+7z+bmvuZvXzciWZWkd0i0xM2qDqz9qxWxVPliXjbaS4RWGyPubOFk
qkGElXG64Yyr+LOLNuAQIlOvAL85.jxRsLkwntFxaCHc5.b2GfyF+JYqvwFa
oiJZYDMOxBJb7XggWYgsgyil0cCXzXEWGZ4NjxR8VV4hr2hL1zQ1W9zm+JCN
cKCJlKsf6ah19xuqpLqAv3kGj4U5LONKZaK0UR3rkEBaoK8dVVzXqQH2neDN
doAgmGrTZzv6V3jwCgLdAIxmnrWrBQPvyiynW4YJYtJT3o9iVtPgJr+KICHA
YczkQ15dGXxnkWooQ7LkmFYz7UQuoqYsPppz0c1BVxoEDNblyCZi5XE0zbRz
x94gVI56ZFLHKQYTl8KXjSCCYpu5ZZZdzP1rNQuRgnjyvG9RAg4YtLC73k3y
aZC2qqaEvqnNnW1azmJ3QyljcpVvvETI0irw+G1B5lAtoV92u+tSD63mBbe2
fZ0wkzw28F8agVK500R6gNx+XR1iPQTzcm8gJXkRAnj8cRBVIao+WToiKmfT
xdN6kYhdxj5TqEpWeOJXHoPjlOEFGCJjAqDGhwwhkw411eFiiFlwU.4wY9D.
IKCZDWvJA4w4TDvw.cHR1TnDj8hrIgIBzH4f20WBQIxDDIW.UnSQxmNqZ2t8
BU+3rcZXxTusyE7UL20sV56xccUh80GmuKqLtRYxwpMIXGTt0E9PtuBJbamI
LVNTOFIanyHoqJ.YUqneWkGD71Z8hMBId1yy9EPHVci9
-----------end_max5_patcher-----------

jit.gl.pixのコードなので注意

余談

記事を書き終わって、そういえば・・・大昔に自分でjit.gl.pixで使うnoise調べてましたわ。今回とアルゴリズム違うのでこちらもご参照

Gen で配列をつくる検討 #Max8

リアルタイムグラフィックスの数学勉強中

リアルタイムグラフィックスの数学

シェーダーの勉強がてら、こちらの書籍をMax8上のGenに移植しています。

このような画像作成の学習を通して、数学やシェーダーの理解が向上できそうです。しかし、Max8で実装していく上では直接的に配列が使えないようで少し困っていました。

解決案(とりあえず)

かなり無理矢理ですが、整数の入力に対して変数を返せば良いと考えてSubpatchを作ってみました。と言ってもselector objectなんですが、0はじまりにしてあります。

Length3の配列

配列の長さを3以上に増やしたければ、根性でinletの数を増やさなければなりません。genにおける配列実装に良い解決案をご存知の方いたらコメント/Twitter等で教えて頂けますとありがたいです。

使用例

色の配列を扱う例(arr3に繋いだ三つ目のベクトルが出力されます)