RSS Twitter Facebook


« 2017年11月 | 2017年12月のアーカイブ | 2018年01月 »

2017/12/30

input type=range タグをカスタマイズするために



これなんですが : 


大晦日なんですけどね。 input-knobs.js というライブラリを作ったりして、ちょっとこの HTML の <input type="range"/> タグという奴と格闘していました。タグ1つで連続値を入力するスライダーが書けるのでとにかく便利。個人的に HTML5 で追加されてよかったタグ第一位くらいに位置するのですが...。

ただ、見た目がね。かなりカオスな事になっています。

現状、シンプルに <input type="range"/> と書いた時に表示されるものが下の図です。興味深いです。Macの方はそれなりに統制が取れているんですけどね。ことデザインに関しては Apple に真っ向から盾突くわけにも行かないとかいう事情があるんですかね? 経緯は知りませんけどみんな Apple の Safari に寄せて来てるんですか? 一方 Win の方はみんな自由すぎ。そもそもの MS Edge が一番浮いてるんじゃないですか。ちょっと癖が強すぎ。ここであまり個性は出してほしくないなぁ。

更に Edge の場合はスライダーの操作中だけ数値が表示されます。これはすごく便利ではあるのだけど Edge でしか表示されないのでこれに頼るわけにも行かないのが現状です。結局数値を読み取る必要がある場合には別の場所に表示する事になります。


という事で検索すれば、この<input type="range"/>タグをスタイルシートでカスタマイズする的な情報もちらほらあるのですが、単発のサンプルだけでは中身がよくわからないので、スライダーを構成している各部品がどうなっているのかをちょっとまとめておきます。


このスライダー全体を指すためのCSSのセレクタは input[type=range] とかで指定できるのですが、詳細なカスタマイズをするには背景やツマミなどスライダー内の各パーツに対してスタイルを適用する必要があります。ボタンのスタイリング等で良く使う :hover や :active 等がエレメント全体の特殊な状態を指す「疑似クラス」と呼ばれるのに対し、このエレメント内の一部分は「疑似要素」と呼ばれ、コロン2つに続くセレクタを使用します。

ただブラウザによって実装が違うので割と面倒です。
取りあえずクロスブラウザで同じ表示になるようなスライダーの背景とツマミ部分の塗りを指定するために必要な情報を考えます。

Chromeの場合:



webkit系 の場合はカスタマイズをする際にまず エレメント本体である input[type=range] と ツマミ部分の ::-webkit-slider-thumb に対して -webkit-appearance:none; を追加してブラウザが独自の描画をするのを止めてから各種の指定をする必要があります。
またこの両方を指定するとエレメントが高さを失いますので height を明示的に指定する必要があります。

::-webkit-slider-runnable-track はエレメント全体の外形と重なっていますが存在するだけで描画にはつかわれていません。

Firefoxの場合:


Firefox にもブラウザの独自描画を止めるための -moz-appearance:none; という CSS の指定があります。ただしこれは明示的に指定しなくても、エレメントの background-color や border をいじった時点で自動的に解除されるようです。

::-moz-range-track がスライダーの溝部分の表示に使われていますが、不要な場合、 display:none; を指定しても消えません。height:0; か opacity:0; ならこれを消す事ができます。

また、Firefox ではツマミ部分にデフォルトで border と border-radius が付いていますので表示を合わせるにはこの辺も指定が必要です。

Edgeの場合:


結構ごちゃごちゃしていますけど、エレメント本体 input[type=range] に対して ::-webkit-appearance:none; を指定すると ::-ms-track、::-ms-fill-lower、::ms-fill-upper がまとめて表示されなく(存在はしているが透明に)なります。
間違いではなく、「-webkit-appearance:none;」です。このブラウザプリフィックスを騙るような事をするのはどうかと思わなくもないのだけど勢力図的にやむにやまれず、という奴でしょうね。

更にツマミ部分も ::-ms-thumb だけでなく ::-webkit-slider-thumb でアクセスできるようになっているので、結果的に -webkit-appearance:none; が指定されている webkit 向けのカスタマイズコードが完全にとは言いませんが割合それっぽく見えるという事になります。

なお、::-ms-tooltip 部分はいらないなら display:none; を使って別途消す必要があります。このツールチップは、display:none; 以外の色指定やサイズ指定等は全く効かないようです。


さて、以上を踏まえて、クロスブラウザで同じ表示になるスタイルシートを作ります。
  input[type=range] {
    -webkit-appearance:none;
    background:#000;
    height:24px;
    width:240px;
    border-radius:8px;
  }
  input[type=range]::-webkit-slider-thumb{
    -webkit-appearance:none;
    background:#f00;
    height:20px;
    width:20px;
    border-radius:50%;
  }
  input[type=range]::-ms-tooltip{
    display:none;
  }
  input[type=range]::-moz-range-track{
    height:0;
  }
  input[type=range]::-moz-range-thumb{
    background:#f00;
    height:20px;
    width:20px;
    border:none;
    border-radius:50%;
  }


どうでしょうか、せっかくなのでちょっと角を丸めたりしています。
こんな感じになっているはずなんですが
画像
実際のタグ

更に...

疑似要素が厄介な所として、複数を並列しては書けないので冗長な感じになってしまいますがしょうがないですね。それに HTML 内でインラインで書く事はできないし、Javascript から element.style.xxx の様なアクセスもできません。

インラインのスタイル指定で疑似要素にアクセスする方法は10年ほど前に提案されていた案があったようなんですが日の目を見る事なく削除されてしまったようです。

クラスや id を振っておいてスタイルシート内のリテラルでカスタマイズするのは問題なくできるのですが、Javascript でこの辺を扱うライブラリを作ろうとすると非常にやりにくいです。結局要素のインスタンス毎に疑似要素の個別スタイルを与えようとすると id を振っておいてグローバルな場所で id 毎にルールを作るような事しかできません。

CSS 内で変数が使える CSS Variables がちゃんと動くようになればもう少し融通が利くようになるのですが、これまた一部のブラウザ上でまだバギーなふるまいがあって今の所まだ実用的じゃなかったりします。もう少しだよ、もう少し。

posted by g200kg : 4:08 PM : PermaLink

2017/12/27

input-knobs.js : 軽量なノブ用ライブラリ



オーディオ系Webアプリでは欠かせないノブ用のGUIライブラリ「webaudio-controls」、何かWebアプリを作る時はだいたいいつも使っています。しかしフレームワークとして使っている Polymer が既に バージョン 2 になり、このままではいかんと思っていじりかけたりしたのですが斜め上方向に進んで、新たなGUIライブラリを作ってしまいました。

input-knobs.jsは「webaudio-controls」のサブセット的なもので、今の所回転するノブとトグルスイッチ、ラジオボタンのみです。これらは基本的な動作は input type="range" とか input type="checkbox" をそのまま使っていて見た目だけ CSS と Javascript を駆使して差し替えます。

HTML5でサポートされたスライダーのタグ、input type="range" が結構有能なのでだいたいこれでも良いんだけどやっぱり回るノブが良いな。とは言え、webaudio-controls だと Polymer ベースで、特に Firefox、Edge だと webcomponents が polyfill なので DOM の基本構造をごっそり書き換えられて困った事になったりしたのでついついやってしまった。

まあ webcomponents でノブ用の独自タグを拡張するという方向が魅力的なので、どのブラウザでも webcomponents がネイティブサポートされれば webaudio-controls で良いんじゃないかとも思うのだけど。HTML imports あたりでいまいち仕様がしゃきっとしないみたいだしもう少し時間がかかるんですかね。

input-knobs.js は 5kB 程度の単一ファイルだし、イベント周りも input タグと同じなので取りあえず input type="range" でプロトタイピングしておいて、input-knobs.js を追加して GUI を整えるというプロセスが快適かな。

GitHub : input-knobs.js
input-knobs.js デモページ

posted by g200kg : 12:21 PM : PermaLink

2017/12/23

2017年 Web Audio API はどう変わったのか?



これは 「WebAudio/WebMIDI API Advent Calendar 2017 Advent Calendar 2017」 用の記事です。
Advent Calendar にはこの他にも Web MIDI/Audio 関係の記事がありますのでよろしければどうぞ。

https://qiita.com/advent-calendar/2017/webaudiowebmidi


W3C サイトで公開されている Web Audio API のワーキングドラフトは2年前から変わらず、2015年12月版のままなんですが、GitHub に置かれているエディターズドラフトは2017年も色々と変更が加わっています。

完全には追い切れていませんが、どんな変更があったのかざっと紹介したいと思います。なお昨年中に行われた変更は昨年の記事、「2016年、Web Audio API はどう変わったのか?」の方にありますので併せて見て頂ければ日本語訳を作った2015年12月以降の様子がだいたいわかると思います。


AudioWorklet の詳細設計と実装が進みました

これが一番の大物で、去年の時点で AudioWorker 改め AudioWorklet の設計が始まっていましたが、deprecate になったScriptProcessor で新たに何かを作るのもいまいち気が進まない事もあり、ブラウザに実装されるのを心待ちにしてやきもきしていた人もいるのではないでしょうか。

設計が進む中で、AudioWorkletNode と AudioWorkletProcessor 間の通信方法が、当初 sendData() / ondata ハンドラーだったのが MessagePort に変更されたりしたようです。

つい最近ですが Chrome 64 でフラグ付きですが実装されていますので、遂に実際に動作を試す事ができるようになりました。

エディターズドラフト : AudioWorklet

AudioContext からレイテンシー関係の情報を取れるようになりました

AudioContext に getOutputTimestamp() というメソッド、およびbaseLatency、outputLatencyというプロパティが追加され、これにより JavaScript 上の処理から実際に音として出力されるまでの時間などが取れるようになります。この辺を使うと、音とグラフィックスのタイミングをびっちり同期させたりする事ができそうですね。

getOutputTimestamp()で取れるのは:

AudioTimestamp {
    double              contextTime;
    DOMHighResTimeStamp performanceTime;
}
という形式で、
  • contextTime : 今現在オーディオデバイスに渡されているデータの AudioContext.currentTime 時間軸上の時刻
  • performanceTime : このデータが実際にオーディオデバイスによって音として出力される High Resolution Time 時間軸上の時刻

です。

また、プロパティの方は、AudioDestinationNode がデータを受け取ってからオーディオサブシステムに渡すまでのレイテンシーが baseLatency、オーディオサブシステムがデータを渡してから音として出力されるまでのレイテンシーが outputLatency となります。outputLatency はプラットフォーム、ハードウェア依存の話になってしまうので OS 毎にざっくりした値が設定されるのではないかと思いますが今の所まだ仕様だけで実装はされていません。


エディターズドラフト : getOutputTimestamp

AudioContext を作成する時のオプションでサンプルレートが指定できるようになりました

AudioContext を作成する際に、

var audioCtx = new AudioContext({
  latencyHint: 'interactive',
  sampleRate: 44100,
});

というような感じで WebAudioAPI の内部のサンプルレートが指定できるようになりました。またもうひとつのオプションである、"playbackCategory" は "latencyHint" に名前が変わっています。

実装は今の所まだ対応していないようですが、指定されたサンプルレートがオーディオデバイスのサンプルレートと異なる場合は内部でリサンプルが行われる事になっているようです。


エディターズドラフト : AudioContextOptions

MediaStreamTrackAudioSourceNode が追加されました

今まであった MediaStreamAudioSourceNode に加えて MediaStreamTrackAudioSourceNode が追加されました。名前長いよ。

これは MediaStream 中の1つのオーディオトラックを指定して Web Audio API に取り込むためのノードになります。

私も動作を確認していないのですが、これは WebRTC のピアコネクションから送られてくるストリームに複数のオーディオストリームトラックが含まれている時などに id で指定して1本のオーディオを取り込む場合等に使うものだと思います。


エディターズドラフト : MediaStreamTrackAudioSourceNode

各ノードのチャンネル数に関する制限等の詳細が明記されました

今までの仕様で既に StereoPannerNode のように信号が2チャンネルステレオでないと意味を成さないノード等もありました。

各ノードの種類に応じて channelCount、channelCountMode、channelInterpretation の各パラメータの扱いの詳細が説明されています。例えば StereoPannerNode では channelCount は2以上に書き換えられず、channelCountMode は"max"に設定できません。また channelSplitter では channelInterpretation を"discrete" 以外には設定できません。

dictionary AudioNodeOptions {
    unsigned long         channelCount;
    ChannelCountMode      channelCountMode;
    ChannelInterpretation channelInterpretation;
};

これらは(new を使って)ノードを作成する際にオプションとして渡す事ができます。


エディターズドラフト : AudioNodeOptions

パラメータのタイプの変更

幾つかのパラメータで Float32Array しか受け付けなかったものが通常の数値の配列で OK になっているものがあります。

  • createPeriodicWave の real、imag 引数
  • setValueCurveAtTime の values
  • WaveShaper の curve

詳細な説明がどんどん増えていて全部を読むのはちょっと大変になってきていますが、他にも細かい所に変更は色々入っていると思います。

W3Cにあるワーキングドラフトがかなり置いて行かれてる感が強まってきましたので、そろそろワーキングドラフトに反映して欲しい所ですかね...

posted by g200kg : 4:05 AM : PermaLink

2017/12/20

Web Audio API のノードの組み合わせでDimensionを作る



これは 「WebAudio/WebMIDI API Advent Calendar 2017 Advent Calendar 2017」 用の記事です。
Advent Calendar にはこの他にも Web MIDI/Audio 関係の記事がありますのでよろしければどうぞ。

https://qiita.com/advent-calendar/2017/webaudiowebmidi


Web Audio API のノードの組み合わせでディメンションエフェクトを作ってみるサンプルです。

その昔、コーラスエフェクトが一般的になり始めた頃、ローランドから発売されたのが「Dimension D」というラックマウントのエフェクターです。ディメンションはコーラスの一種ではありますが、通常のコーラスエフェクトで感じるピッチの揺らぎがあまりなく、それでいて良い感じの広がりがあるコーラス感が得られるという事で一般的なコーラスエフェクトとは一線を画す地位を確立しました。

「ディメンション」自体は商品名に由来する名前ですのでエフェクトの一般名称としては「多層コーラス」のように呼ばれる事もありますが、本家の Dimension D はステレオの左右チャンネルの個別処理を行うだけですので多層というほど色々積みあがっているわけではありません。

さて、Web Audio API のノードの接続としては下の図の通りです。ステレオの左右チャンネルを ChannelSplitter で分離し、個別に Delay をかけて、原音とミックスします。ミックス先は LR 反転が基本ですが、ストレートにミックスするラインに混ぜる事もできます。コーラスの元、揺らぎの元となる LFO からのディレイタイムへのモジュレーションはかなり控え目で、さらに LR のチャンネルでモジュレーションの極性が反転しています。

下のリンクから飛んで、左上の [Start] ボタンで音が出ます。ツマミは Rate がモジュレーションの速度、Depth がモジュレーションの深さ、Mix は LR のストレートミックスの量です。
なお、本物の Dimension D は本体にボタンが5つあるだけで、OFF / MODE 1~4 というプリセットされた設定を選択するのみという実に潔い仕様のエフェクターです。絶妙なプリセットのチューニングあってのディメンションですので本物と同じというわけにはいきませんが、雰囲気を感じていただければと思います。

※ あ、ちなみに今の所 Chrome の ChannelSplitter はデフォルトでモノラルの信号を突っ込むと 最初の output に信号が出てきません。これは古い仕様のChannelInterpretation に従っているためなので ノードを作成する時に createChannelSplitter(2) とチャンネル数を明示的に指定する必要があります。多分そのうち修正されると思います。

Dimension Sample

posted by g200kg : 10:25 PM : PermaLink

2017/12/19

Web Audio API のノードの組み合わせでBitCrusherを作る


これは 「WebAudio/WebMIDI API Advent Calendar 2017 Advent Calendar 2017」 用の記事です。
Advent Calendar にはこの他にも Web MIDI/Audio 関係の記事がありますのでよろしければどうぞ。

https://qiita.com/advent-calendar/2017/webaudiowebmidi

Web Audio API のノードの組み合わせでビットクラッシャーを作ってみるサンプルです。ビットクラッシャーは意図的に信号のビット数を減らして Lo-Fi な音を作り出すエフェクターですね。デジタルで処理するエフェクトとしてはとても簡単なので DAW 等におまけ的に付いていたりして一般的に認知された気がします。ギター用等のハードウェアのエフェクターとしてもあまり数はありませんが無くはないです。

このサンプルは WebAudioDesigner というツールで作っていますので、実際に動作を確かめられます。下の方にあるリンクから飛んで左上の[Start]ボタンを押すと音が出ます。[On]のボタンでエフェクトの On/Off が切り替わります。

処理の内容としては WaveShaper で階段状のカーブを作っておき、それに通すだけになります。
このカーブは画面上ではただの直線に見えますが、長さが1023の配列で -1~+1 の範囲の 256段の階段状のカーブです。 "curve"の文字列の部分をクリックすると出てきますが、作成部分は下のコードのようになっています。
(()=>{
  var r=new Float32Array(1023);
  for(var i=0;i<512;++i){
    var v=((i/512)*128|0)/128;
    r[511+i]=v;
    r[511-i]=-v;
  }
  return r;
})()
パラメータは"Bits"の1つだけで 2ビットから8ビットまで可変できますが整数に限らず少数でも構いません。通常のやり方だとこのパラメータによって任意の段数のカーブを作り直すのですが、ここでは少し違うやり方で、信号の振幅の方を調整してカーブの一部のみを使う事で任意の段数に変換しています。

それが WaveShaper の前後にある Gain で Math.pow(2,x)/256 および 256/Math.pow(2,x) の部分です。

とにかくノードの数を減らしたいという場合は別ですが、毎回カーブを作り直すよりはこの方が応用は効くんじゃないですかね。

この curve のパラメータのテーブルは以前は補間をするべきかどうかが仕様で定まっておらず、テーブルのサイズが小さいとブラウザの実装によって勝手に階段状になったり直線になったりしていたのですが、現在の Web Audio API の仕様では直線補間されると明確に定義されたので、階段をちゃんと表現するにはそれなりのサイズが必要になります。

この WaveShaper というノードはディストーション系の効果を得るために使うというのが主な用途になります。BitCrusher もディストーションの一種と言えなくもないですが、他にもアイデア次第で面白い使い道がありそうです。

そもそも音声信号に適用するだけではなくて制御系の信号に適用して妙なモジュレーションを掛けたりなんかもできますよ。

BitCrusher Sample

posted by g200kg : 5:04 PM : PermaLink

2017/12/17

Web Audio API のノードの組み合わせでAutoWahを作る


これは 「WebAudio/WebMIDI API Advent Calendar 2017 Advent Calendar 2017」 用の記事です。
Advent Calendar にはこの他にもWeb MIDI/Audio 関係の記事がありますのでよろしければどうぞ。

https://qiita.com/advent-calendar/2017/webaudiowebmidi




WebAudioAPIのノードの組み合わせでオートワウを作ってみるサンプルです。WebAudioAPIってノードの組み合わせだけで結構色んな事ができるんですけど、何をどう組み合わせれば良いかを考えるのはエフェクトの中身がわかっていないとなかなかハードルが高いですね。

さて、「オートワウ」あるいは「タッチワウ」と呼ばれるエフェクターですが、ギターのエフェクターでみょんみょん言う奴ですね。中身は単なるQが高めのレゾナントフィルターなんですが、これのカットオフ周波数をペダルで操作できるようにしたものが「ワウペダル」で、それをピッキングの強さで自動的に変化させるようにしたものが「オートワウ」です。

ピッキングの強さで変化するというのは入力される信号の振幅の大きさを取り出して制御に使うわけですがこの部分をエンベロープフォロワと呼びます。

ノードの繋ぎ方は下の図のようになります。左上の方にWaveShaperとBiquadFilterがありますがこれがエンベロープフォロワに相当します。WaveShaperのカーブは0を中心に左右対称の[1,0,1]になっていますのでマイナスの入力は全部プラスに折り返されてしまいます。そしてBiquadFilterのlowpassを通りますがこのカットオフは3Hzという非常に低い周波数になっていますので音声波形そのものではなく、大体の音量の変化に追従した値が得られます。

後はこれに適当な倍率を掛けてフィルターの周波数を操作するだけです。後、右側半分の方にあるのはOn/Offのバイパススイッチや波形表示をしているだけです。

WebAudioDesignerというツールで作っていますので、実際に動作を確かめられます。下のリンクから飛んで左上の[Start]ボタンを押すと音が出ます。[On]のボタンでエフェクトのOn/Offが切り替わります。

このエンベロープフォロワの部分は他にも色々応用が効きますので覚えておいて損はないかと思います。

AutoWah Sample

posted by g200kg : 3:04 AM : PermaLink

2017/12/16

WireとCordとCable


例外も多いし、多分これに沿っていなくても誰にも怒られない知見。
いわゆる電線をワイヤーとかコードとかケーブルとか呼ぶ使い分けについて
  • ワイヤーは電線そのもの。導体1本でもワイヤーだし絶縁する被膜がなくてもワイヤー
  • コードは主に家電機器の電源を繋ぐために使用される電線を指す言葉。電安法が「コード」を使ってるからそういうニュアンスが強くなった模様
  • ケーブルは複数の電線をまとめて更に被膜(シース)でくるみ、1本にしたもの
まあ慣例的にこうじゃないものも多分たくさんあるし、割とどうでも良い話ではあるけど。

ただまあ
「ワイヤー」は凄く細そう
「コード」は柔らかくてひょろそう
「ケーブル」はコードよりごつそう
というイメージではある。スピーカーコードよりスピーカーケーブルの方が高そう。

あー、後は「シールド」というのもあるな。楽器に直接ささるシールドケーブル限定で略す時に前半分が残った感じだけどこの言い方をするのはほぼギター/ベースプレーヤー。英語圏だと多分通じない。CableとかGuitar cable とか言っている感じ。

posted by g200kg : 12:55 AM : PermaLink

2017/12/04

第17回アナログシンセビルダーズサミット(ASBS17)


12月2日、北の丸公園の科学技術館で年末恒例、第17回アナログシンセビルダーズサミット(ASBS17)が開催されました。
今回は初出展の人も結構いて初めて見るものも多く新鮮でした。

※前から思ってた事だけど、名前が長すぎて「シンセサミット」とか「ビルダーズサミット」とかいつも適当な省略の仕方をするのでググラビリティ的にどうよと思わなくもない。なおTwitterのタグ的には #ASBS17 で統一されています。

会場はここ、武道館の隣の科学技術館です
会場準備中の様子
私はいつものDMX照明セットを並べています。もう今年のネタはこれで押し通してしまった
会場入り口付近で余剰部品の頒布が行われています
シンセDIY界のレジェンド山下さんがついにEuroRackに手を出しました。ライブ映えを考慮してアクリルパネルにLEDでかなり派手派手な感じに。
denha's channel の原田さんの所はLEDバッジや謎ガジェットの小物がいっぱい
houshuさんの屏風シンセ。中身は過去の作品や作りかけの詰め合わせのようです
これは凄い。DIYで良くここまで作ったと感心。仕上げも凄いが中身も音色メモリー付きのアナログ6音ポリシンセでぎっしり詰まっている感じ。部屋のスミスさん作。
一方こちらはDigiLogさんのブースにあった段ボール箱シンセ。ご家庭に良くあるamazonの箱に入っています。パンク感が良い感じに振り切れてる。DigiLogさんの出展のメインはOCTAの方だと思うけどこっちが気になる
sigboostさんもASBSに初参戦。MAXで作った楽器のプログラムをFPGAに落としてハードウェア化するという以前IPAの未踏プロジェクトにもなってた奴です
Maker Faireなんかでも見てたのですがASBSは初参戦らしい。risgkさんのArduinoシンセ。8ビットCPUの性能の限界に挑戦して3音パラフォニック。
DCO+アナログフィルターの5音ポリシンセとパラメータ操作用の専用コントローラという構成のシンセ。Yoroheiさん作
Hitoteさんの謎楽器。ボタンが2オクターブ2段の鍵盤になっていてシンプルなんだけどこれは面白い。ライブとかで映えそう
うーえさん。Native Instruments の Massiveのようなシンセをアナログハードウェアで実現するという壮大な計画。24VCO/72VCA/32EG/32LFO 等々えらい事になっている模様

今回若い人の参戦が増えてだいぶ出展者の平均年齢が下がりましたかね。

しかも皆ポリフォニックのハードウェアアナログシンセのようなかなり高度なものを手掛けています。やる人はやるもんですね。未来は明るいんじゃないかな。

posted by g200kg : 12:13 AM : PermaLink


« 2017年11月 | 2017年12月のアーカイブ | 2018年01月 »

g200kg