mohayonao / coffeecollider Goto Github PK
View Code? Open in Web Editor NEWSound Processing Language for Web Audio
Home Page: http://mohayonao.github.io/CoffeeCollider/
License: MIT License
Sound Processing Language for Web Audio
Home Page: http://mohayonao.github.io/CoffeeCollider/
License: MIT License
CombN / CombL / CombC
AllpassN / AllpassL / Allpass C
案
template = SynthDef (out, osc)->
(freq=440, amp=0.5)->
Out.ar(out, osc.ar(freq) * amp)
こう書いた場合は
def1 = template.build(0, SinOsc)
def2 = template.build(1, LFSaw)
def1.play freq:880 # out 0 に SinOsc
def2.play freq:660 # out 1 に LFSaw
こう書けるので便利そう。
テンプレート引数は省略できて以下の2つは同じように解釈されたほうが良い。
def = SynthDef (freq, amp=0.5)->
Out.ar(0, SinOsc.ar(freq) * amp)
def = SynthDef ->
(freq, amp=0.5)->
Out.ar(0, SinOsc.ar(freq) * amp)
from
@wait 1000 # 1000msec
to
@wait 1 # 1sec = 1000msec
雑談用です
...
Synth.def ->
Out.ar([0, 1], SinOsc.ar())
.play()
a = syncblock ->
100
console.log typeof a # => "function"
console.log a() # => 100
Task.do ->
s = def.play().on("end", ->
s.stop() # s is undefined
)
.play()
compiled
Task.do ->
s = def.play().on("end", do (s)->
->
s.stop() # s is undefined
)
.play()
improved ?
Task.do ->
s = do (s)->
s = def.play().on("end", ->
s.stop() # s is valid
)
.play()
var cc = new CoffeeCollider();
cc.execute("(-> SinOsc.ar() ).play()").play();
Uncaught ReferenceError: SinOsc is not defined
coffeecollider -e "(->SinOsc.ar(440)).play()"
Pseq([1,2,3], 10).do (i)->
console.log i
SynthDef ->
Out.ar(0, Mix.fill(24, (i)->
SinOsc.ar(440 * (i).midiratio())
) * 1/12)
.play()
compiled
((global)->
(SynthDef(->
cc.Out.ar(0, cc.Mix.fill(24, (i)->
cc.SinOsc.ar((440.__mul__((i).midiratio())))
).__mul__((1.__div__(12)))))
).play(), [] # <- ERROR!!!!
).call(cc.__context__, this.self || global)
タスクの中で wait をするときに例えば「a, b, c が終了するまたは1000msec経過する」のような複雑な条件を指定したい。その書き方について検討する。
@wait or(and(a, b, c), 1000)
これは分かりやすいけど、グローバル関数 or, and を消費する。
@wait @or(@and(a, b, c), 1000)
これだとグローバル関数は消費しないけどやかましい感じがする。
@wait (a * b * c) + 1000
演算子の拡張を使った書き方。分かりにくいし、演算子拡張メソッドの中が複雑になる。
@wait (a && b && c) || 1000
演算子の拡張を使った書き方その2。&&
と ||
を新しく拡張する必要があり、他のコード部分に影響がでそう。wait関数に続く場合のみ拡張するなら可能か?
# これはOK
@wait (a && b && c) || 1000
# これはNG
token = (a && b && c) || 1000
@wait token # true と評価されて無限に wait する
演算子の拡張を使った場合、n個のタスクを対象にするというのが書きにくい。配列を入力できるようにすると以下のように書けるけど分かりにくい?
@wait (1 && [a, b, c]) || 1000
&&
のときは 1 に続ける。||
のときは 0 に続ける。
output NaN when using unread buffer
140sc みたいな要領でツイッターに投稿できるサイズで coffee-collider コードを書きたい。
よく使いそうなものは 一文字クラス名、メソッドを用意する。
SinOsc.ar(440).play()
SinOsc.ar(440).p()
( Task.interval 100, ( -> synth.play() ) ).play()
(T.i 100, (->s.p())).p()
var cc = new CoffeeCollider({ audioContext: new AudioContext() });
cc.getWebAudioComponents();
// return [ AudioContext, ScriptProcessorNode ]
A4.midicps() # 220 (wrong)
"A4".midicps() # 440 (correct)
音が崩れる。バッファサイズの調整が必要。
Line.kr(0, 1, 10, doneAction:2) # 2 is elusive
I want to write like this.
Line.kr(0, 1, 10, doneAction:FREE) # (replaced 2 when compiling)
List of UGen-doneAction is here.
http://doc.sccode.org/Reference/UGen-doneActions.html
What aliases is good?
send a massage
// in client
cc.send("message", {value:100})
# in CoffeeCollider
Message.on 'message', (data)->
console.log data # => {value:100}
receive a message
// in client
cc.on("message", function(data) {
console.log(data); // #=> {value:100}
});
# in CoffeeCollider
Message.send 'message', {value:100}
MMLでスケジューリングできたら便利だと思う。
Task.mml mml, (data)->
# do something
.play()
error
[1,2,3] +S+ [1,2,3,4,5,6,7,8,9,10]
compiled
[1, 2, 3](S.__plus__().__add__([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))
ok
[1,2,3]+S+[1,2,3,4,5,6,7,8,9,10]
compiled
[1, 2, 3].__add__([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], cc.SHORT)
Max/MSPのような時間値シンタックスを導入したい。
http://www.cycling74.com/docs/max5/vignettes/core/maxtime_syntax.html
Line.kr(0, 1, dur:"1.0.0") # 1小節かけて 0 から 1 に変化する
実装案
対応策
@wait "1.0.0" * 1000 # 1小節待つ
SinOsc.kr("~1.0.0") # 1小節を周波数に変換する ( ~ はサイン波のイメージ)
記法 (案)
100hz
→ 0.0150ms
→ 0.0510sec
→ 101min
→ 6000:03:25.230
→ 205.2301000samples
→ (1000 / samleRate)1000samples/44100hz
→ (1000 / 44100)以下はマスターBPMとの連携が必要となり、省略した場合は定数として扱えない
L4
bpm140 L4
→ 0.428571428571428552.3.240
bpm140 2.3.240
→ 4.928571428571428480ticks
bpm140 480ticks
→ 0.42857142857142855The below code reproduces it.
SinOsc.ar([440,660]) * Line.kr(0, 1) #=> BinaryOpUGen ???
it should be like this.
SinOsc.ar([440,660]) * Line.kr(0, 1) #=> [ BinaryOpUGen, BinaryOpUGen ]
コードの表現について。こんな感じで書く?
Chord("M7", 1).toDegrees() #=> [ 4, 7, 11, 12 ]
Chord("M7", 1).toFreqs(440) #=> [ freq... ]
Chord("M7", 1).toRatios() #=> [ ratio... ]
source
Synth.def ->
Out.ar(0, SinOsc.ar(440))
.play()
replaced (prefix cc)
cc.Synth.def ->
cc.Out.ar(0, cc.SinOsc.ar(440))
.play()
template = Task (a, b)->
(i)->
s = def.play()
s.set freq:a * i
@wait b
s.set freq:a * i * 2
@wait b
task1 = Task.do(10, template(440, 0.50)).play()
task2 = Task.do(10, template(660, 0.45)).play()
WebSocketに対応させることで、それぞれのクライアントで書いたコードに基づいてサーバーが信号処理を行い、その結果を共に聞くといったソーシャル音響プログラミングが可能になる。現在のWorker内で eval して信号処理を行う方法をそのまま WebSocketServer に対応させた場合、サーバー内で eval することになり良くない。そこでOSCのようなメッセージのやりとりでサーバーを制御する構成に作り変えたい。ただし、一般的な用途であるローカルでの運用が複雑になったりUIとの連携の遅延が大きくなってはならない。ソケットサーバーでの運用はUIとの連携は考えない。
SynthDef ->
Out.ar(0, Mix.fill(24, (i)->
SinOsc.ar([440, 441] * (i).midiratio()) * 1/12
))
.play()
caught
Uncaught TypeError: Cannot read property 'inputs' of undefined
from #2
BPMを省略した場合はマスターテンポに連携させたい
Task.do ->
Master.setBPM 120
s.play freq:440, dur:"L8"
t = Task.do ->
Master.setBPM 140
s.play freq:660, dur:"L4"
@wait 100
Master.setBPM 180
s.play freq:660, dur:"L4"
@wait 100
.play()
# @wait t
s.play freq:440, dur:"L8" # ここのBPMは?
@wait 1000
.play()
Like this?
// in the client
var cc = new CoffeeCollider();
$button.on("click", function() {
cc.send("button-click", 1000);
});
cc.recv("response-from-server", function(data) {
console.log(data); //=> [100,200]
});
# in the server
Message.recv "button-click", (data)->
console.log data #=> 1000
Message.send "response-from-server", [100, 200]
必要なモジュールだけ組み込んでビルドできると良い。
a syncblock function does not do repeatedly.
Task ->
[ 1, 2, 3 ].forEach syncblock (i)->
console.log i
.start()
# expected console out : 1, 2, 3
# actual: 1
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.