LoginSignup
0
0

More than 1 year has passed since last update.

RNBOのWeb出力を試す

Last updated at Posted at 2023-01-04

Max8の新機能RNBOのWeb出力を試したときの備忘録です

まず
Maxで音が鳴るRnboを使ったパッチを作る。

image.png

image.png

パッチ内容

これは、frequencyとvolumeで
サイン波形が鳴るパッチ

パラメータ drum というのに0.00 1.00の値を入れることで
ドラムの音が鳴るパッチになります。
wavファイルはパッチと同じところに置いておきます。

export時にCopy Sample Dependencesを入れておくとmediaフォルダに波形がコピーされます。
image.png

Cyclingのrnbo.exampleで動かす

https://github.com/Cycling74/rnbo.example.webpage
このページにあるものを動かしてみます。
これをクローンしてきて、

このexportフォルダにMaxで出力したファイルをコピーします
image.png

image.png

Webサーバーを起動する

コマンドラインから
npx http-server
を実行してサーバーをうごかします。

image.png

ブラウザで

URLに
http://10.16.191.211:8080
を入れて実行すると

image.png

スライダーのdrumを動かすと音がします

キャッシュ無効にしておく

作成中キャッシュが残っていると更新されないので
ブラウザでF12キーを押してNetworkにある
Disable cacheをチェックしておく

image.png

P5JSで音を鳴らしてみる

index.htmlを以下のように書き換える

index.html
<html>
  <head>
  </head>
  <body>
    <script type="text/javascript" src="js/guardrails.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.0/p5.js"></script>
    <script src="sketch.js"></script>
  </body>
</html>

image.png

index.htmlと同じ階層に
sketch.jsを用意し

以下のようなコードを書く

sketch.js
function loadRNBOScript(version) {
    return new Promise((resolve, reject) => {
        if (/^\d+\.\d+\.\d+-dev$/.test(version)) {
            throw new Error("Patcher exported with a Debug Version!\nPlease specify the correct RNBO version to use in the code.");
        }
        const el = document.createElement("script");
        el.src = "https://c74-public.nyc3.digitaloceanspaces.com/rnbo/" + encodeURIComponent(version) + "/rnbo.min.js";
        el.onload = resolve;
        el.onerror = function(err) {
            console.log(err);
            reject(new Error("Failed to load rnbo.js v" + version));
        };
        document.body.append(el);
    });
}

let frequency = null;
let volume = null;
let drum = null;

async function setuptat() {
	
    // Create AudioContext
	const WAContext = window.AudioContext || window.webkitAudioContext;
	const context = new WAContext();
	
    // Create gain node and connect it to audio output
    const outputNode = context.createGain();
    outputNode.connect(context.destination);
	
    const patchExportURL = "export/patch.export.json";
	
	response = await fetch(patchExportURL);
    patcher = await response.json();
        
	if (!window.RNBO) {
        // Load RNBO script dynamically
        // Note that you can skip this by knowing the RNBO version of your patch
        // beforehand and just include it using a <script> tag
    	await loadRNBOScript(patcher.desc.meta.rnboversion);
    }
	
	rawPatcher = await fetch("export/patch.export.json");
	patcher = await rawPatcher.json();

	device = await RNBO.createDevice({ context, patcher });
  
  frequency = device.parametersById.get("frequency");
  volume = device.parametersById.get("volume");
  drum = device.parametersById.get("drum");
    
        // (Optional) Fetch the dependencies
    let dependencies = [];
    try {
        const dependenciesResponse = await fetch("export/dependencies.json");
        dependencies = await dependenciesResponse.json();

        // Prepend "export" to any file dependenciies
        dependencies = dependencies.map(d => d.file ? Object.assign({}, d, { file: "export/" + d.file }) : d);
    } catch (e) {}
    	
        // (Optional) Load the samples
    if (dependencies.length)
        await device.loadDataBufferDependencies(dependencies);
    
    // Connect the device to the web audio graph
    device.node.connect(outputNode);
}


function setup(){
    
  //キャンバスを作成
  createCanvas(600,425);
  //背景色
  background(0);
    //オブジェクトの色
  fill(0,255,0);
  //キャンバスの中心に直径100pxの丸を描画
  //ellipse(width/2,height/2,100);0
  fill(0,255,0);
    
}
class Robot {
	
	constructor( inX, inY, inDx, inDy)
	{
		this.x = inX;
		this.y = inY;
		this.dx = inDx;
		this.dy = inDy;
	}
	
	update()
	{
		this.x = this.x+this.dx;
		this.y = this.y+this.dy;
		
		if (this.x < 0 || this.x > width){
			this.dx = -this.dx;
		}
		if (this.y < 0 || this.y > height){
			this.dy = -this.dy;
		}
		
		
		ellipse(this.x, this.y, 80, 80);		
		
		if(frequency != null)
		{
			frequency.value = 220+this.x;
  			volume.value = 0.5 + (height-this.y)/height*0.5;      
  			
			drum.value = robot.x/width;	
			//print(drum.value);
  		}
	}
}

let  robot = new Robot(100,100,10,10);
var t = 0;

function draw() {
	if (isUserStarted) {
		background(0);
		t+=5;
	//	t = t%50;
	//	ellipse(mouseX+t, mouseY, 80, 80);	
	//	
	//	if(frequency != null)
	//	{
	//		frequency.value = 220+mouseX+t;
  	//		volume.value = (height-mouseY)/height;      	
  	//	}
  		
  		if(robot != null){
  			robot.update();
  		}
	}
}

var isUserStarted = false;

function touchStarted() {
    if (!isUserStarted) {
        // touchStarted()を1回だけ呼び出されるようにする
        print('touch');
		setuptat();
		
        isUserStarted = true;
    }
}




function mouseClicked() {
	robot.x = mouseX;
	robot.y = mouseY;
	
	robot.dx = mouseX;
	robot.dy = mouseY;
	

}

やっていることは、WebAudioの初期化と接続
RNBOのexport.json読み込み
frequency,volume,drumのパラメータ関連付け
dependenciesからbuffer読み込み
を初回タッチした時にしています。

こんな感じに動きます
(Cycleを鳴らす場合は多少修正必要)

追記メモ:
音声入力とかを試したい場合、Chromeとかだとhttpの場合localhost:8080とかでないとマイクデバイスがブロック解除できないかも

0
0
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
0
0