【家で遊ぶ】Javascript で簡易サンプラー

Photo by Kofi Nuamah Barden on Unsplash

Javascript を使ってブラウザの Chrome で鳴らせる簡易サンプラーを作ってみます。

こんなの。

DJブースの隅やイベント会場に置いてあるやつです。

爆発音を鳴らしてみたり、録音機能があったり、パターンを保存して再生する機能が付いてあったり、利用場面に合わせて様々な使われ方をされます。

ビートボックス、リズムマシンとも呼ばれたりします。

Tone.js

今回は、簡易版ということで、音が3つ鳴るだけのサンプラーです。

作成に当たっては、偉大なる Web Audio framework の Tone.js を利用します。

A Web Audio framework for making interactive music in the browser.
https://github.com/Tonejs/Tone.js/

動作デモ

まずは見ていただいた方が早いと思うので、 作ったものを netlify に上げておきました。

netlify.app

Chrome 以外では確認していません。
音が出るので注意。
PC、最近のスマートフォンなら動くと思いますが、環境によってはブラウザの「音声」を許可する必要あり。

やってること

主要部分はこんな感じになります。

!function(){
	Tone.Transport.bpm.value = 80;
	Tone.Transport.loop = false;
	const sampler = new Tone.Sampler({
		'C1' : '/bd.mp3',
		'E1' : '/sd.mp3',
		'F#1': '/hh.mp3'
	}, ()=>{
		console.log('initialized')
	}).toMaster();
	const sound = note => {
		const cell = document.querySelector('[data-note="'+note+'"]');
		sampler.triggerAttackRelease(note, .3);
		cell.style.animationName = 'fade1';
		setTimeout(()=>{
			cell.style.animationName = '';
		}, 300)
	}
	const beatbox = document.getElementById('petit-beatbox');
	beatbox.querySelectorAll('div').forEach(div=>{
		div.onclick = e => {
			sound(e.currentTarget.dataset.note)
		};
	});
	document.body.onkeypress = e => {
		if (e.code === 'KeyA') {
			sound('C1');
		} else if (e.code === 'KeyS') {
			sound('E1');
		} else if (e.code === 'KeyD') {
			sound('F#1')
		}
	}
}();

赤、黄、緑の四角をクリックするか、キーボードのASDでそれぞれ鳴らしたい音が再生されるようイベントリスナーをセットします。

ほぼこれだけです。

ボタンを追加して効果音や音色を設定していけば色々遊べます。

Javascript なので、その気になれば、その場でソースコードごと変更してしまうことも可能です。

(ラグがある場合は音自体の軽量化までやらないと駄目かも…)

家で遊ぶ

Tone.js には様々な API が用意されているので、頑張ればエフェクターやシーケンサーとしての機能も追加できます。

Tone.js っょぃ。

逆に、Tone.js のない標準の Web Audio API は、かなりしんどいです。
「シンプルなサイン波を440Hzで3秒間ほどほどの音量にして鳴らす」だけでもう再起不能に陥り寝込んでしまいます。

おうちで自家生産、サンプラーを作って遊んでみるのはいかがでしょうか。


おうち時間で爆弾解除をしてみた話

こんにちは。デザイナーのMです。

新型コロナウィルスの影響で、弊社は約1ヶ月前頃から在宅での勤務体制となっています。
プライベートでも、週末は近所を少し散歩するぐらいしか外出をしておらずほとんど家の中で過ごす、いわゆる「おうち時間」を実践しています🏡
ただ、1ヶ月近く家の中で過ごしていたらさすがにやることも少なくなってきます。。
「ウォーキング・デッド」という海外ドラマをずっと観ていたのですが、それも最新エピソードまで追いついてしまい次に観るのを何にしようか悩んでいるところです😂

そんなとき後輩デザイナーが日報に、あるゲームを紹介しているのを読んで興味が湧き、やってみようと思いました。

それがこちら、
「完全爆弾解除マニュアル:Keep Talking and Nobody Explodes

https://keeptalkinggame.com/ja/



タイトルだけで面白そうじゃないですか?(私だけでしょうか👀
PS4やNintendo Switch、PCのマルチプラットフォームに対応しているインディーゲームです。

どんなゲームか簡単に説明すると、『2人以上で会話をしながら爆弾解除にチャレンジする独特なシミュレーターゲーム!』です。
1人が「処理担当者」となり、ゲーム画面を見ながら画面内の爆弾の状況を説明して、その他の人は「分析担当者」となり「処理担当者」から説明された爆弾の状況を<爆弾解除マニュアル>を見ながら解除方法を「処理担当者」に伝えて、協力しながら一つの爆弾を解除するのです。
要するに、いかに相手に情報をうまく伝えることができるかを試されるゲームです。

「処理担当者」はマニュアルを見れない、「分析担当者」は爆弾が見れないので目で見た情報を丁寧に分析して相手に伝える必要があるので本当に難しいです。
デザイナーたるもの「伝える」ことが仕事だと思っているので、やっている最中はいかにわかりやすく相手に伝えられるかを意識してプレイしました😂

価格は1,600円(Nintendo Switch版)で、<爆弾解除マニュアル>はこちらから無料でダウンロードすることができます。
印刷したほうが雰囲気は味わえるのですが、スマホやタブレットで閲覧しても特に問題なく利用できました。

爆弾の状況を分析する際にメモは必須です。マニュアルに書いてあるヒントをもとに、必死に解除方法をメモ帳に状況を書き殴りながら考えました(笑)


以下、プレイ画面です。


爆弾には「モジュール」という部品が付いていて、この「モジュール」をマニュアルに書いてあるヒントをもとに解除していきます。
爆弾に付いているすべての「モジュール」を解除すれば、爆弾解除となります。
また、アラーム音やBGMが程よく緊張感を与えてくれます。
1回間違えるごとに残り時間の進みが少しだけ早くなるのでさらに焦ります(笑)


「ノーマルモード」と「フリーモード」の2つのゲームモードがあります。

「ノーマルモード」は、ミッション形式になっていて進むごとに解除が必要なモジュールが増えて難しくなります。(私は4つめのミッションぐらいから詰みはじめました笑)

「フリーモード」は、モジュール数や制限時間を自由に設定できるモードです。好きなミッションを作って遊べます。

プレイしているとあっという間に時間が過ぎて、暇になりそうだったおうち時間がはかどりました🏡
パズルゲームやパーティーゲームが好きな方にはとてもおすすめなので、ぜひプレイしてみてください🎮スマホアプリ版があればもっと手軽にできるかなと思いました。開発会社さんよろしくおねがいします(笑)

コロナで皆さん大変かと思いますが、少しでもおうち時間が楽しい時間になるように、いろいろなものを今後も取り入れていきたいと思います👌


コミュニケーションって難しい

こんにちわ。
リエです。

突然ですが、日常生活の中でなんかこの人と話が噛み合わないな〜と感じることってありませんか?私はあります(小声)
話が噛み合わない=コミュニケーションが取れていないので、改善する必要があるのですが、なぜ共通の話をしているのに噛み合わないのでしょうか。
色々な原因がありますが、割とポピュラーなケースを今回はご紹介したいと思います。

話が整理されておらず、相手に目的が伝わっていない

「なんで話が通じないんだろう」というとき、自分の伝え方に問題はないでしょうか。相手のコミュニケーション能力が高い場合は、話が整理されていなかったり結論がまとまっていなくてもある程度内容を汲み取ってくれますが、整理がされていない話を聞くのは疲れるし困ってしまいます。
俗に言う[何を話したいのかがわからない]状態です。
ビジネスの上ではこれは割と致命的。かつ忙しい相手に話すのであればなおさら話を整理し簡潔に伝える必要があります。
きちんと自分が何を伝えたいか整理して伝えるようにすると円滑にコミュニケーションがとれます。

まわりくどい言い方をしている

思わず結論は!?と聞いてしまうほど、まわりくどい言い方する人いますよね。。私はビジネスメールの書き方や話し方は結論から先にというのを教わりました。お仕事を続けていく上でこれは本当に大事だなと感じています。
こちらから発信するというのは相手の時間を頂戴しているという事なので、簡潔にわかりやすく紛らわしい表現はしないようにというのを常に意識しています。話の組み立て方で「PREP法」という法則があるのですが、うまく組み立てられない〜!となった時はこの法則を使うといいと思います。
〜PREP法とは?〜
PREP法は主にビジネスシーンで用いられる文章構成方法であり、簡潔かつ説得力のある文章を作成する際に用いられる。
Point(結論)
Reason(理由)
Example(事例、具体例)
Point(結論を繰り返す)
参考:https://ja.wikipedia.org/wiki/PREP%E6%B3%95

後はメールは話し言葉で書かないことも大事かなと個人的に思っています。※時と場合による

相手が話を聞いていない

これは相手側に原因がある場合ですね。もちろん話を聞いていないというのは時と場合にもよりますが、(相手が忙しい時に話した、そもそも他人の意見を聞かないタイプなど)その場合は別のアプローチを考える必要があります。
自分の意見が100%正しいと思っていて、他人の意見を受け入れない人もこのタイプですね。この場合改善するのは大変ですが、諦めず相手の性格的にどのような方法だったら話を聞いてくれるか考えてみましょう。

話の内容を理解してくれようとしない

一生懸命話しをわかりやすく伝わるように努力しても、理解してくれない場合があります。相手によって理解の方法は異るので(例えば文字や図を交えて説明した方が理解してもらえるなど)模索しながら相手にも理解してもらう方法を考える必要があります。

まとめ

話が通じない・噛み合わない原因は色々ありますが、

色々考えたり経験した中で「話が通じない・噛み合わない→自分はちゃんと伝えているのに・・・」ではなく「一歩引いてこの人にはどうやってアプローチしたらいいんだろう」と考えるようになりました。
コミュニケーションを取ることを諦めるのは簡単ですが、そうすると何も解決しません。なので諦めず柔軟にコミュニケーションを取っていきたいと思います。


SolrのDateRangeFieldで日時の範囲を扱う

はじめに

Solrで日時を扱うためのフィールドタイプとして、通常使う DatePointField の他にもう一つ DateRangeField があります。その名の通り幅の有る時間を取り扱えます。

DateRangeFieldとDatePointField

店舗の営業時間を扱うことを考えてみます。

<fieldType name="pdate" class="solr.DatePointField" docValues="true"/>
<field name="start" type="pdate" indexed="true"/>
<field name="end" type="pdate" indexed="true"/>

与えられた時刻(たとえば2020年3月1日19時)に営業している店舗を調べるには、営業開始時刻(start)と営業終了時刻(end)のフィールドを定義して、「startが2020年3月1日19時よりも前」かつ「endが2020年3月1日19時よりも後」である店舗を検索します。 (話を簡単にするためこの記事ではタイムゾーンのことは考えないことにします)

start:[* TO 2020-03-01T19:00:00Z] AND end:[2020-03-01T19:00:00Z * TO]

対して DateRangeFieldを使えば、営業時間のフィールドが1つで済みます

<fieldType name="rdate" class="solr.DateRangeField" docValues="true"/>
<field name="start_end" type="rdate" indexed="true" multiValued="true"/>

投入するデータは以下のような形式です。

[
    {
     "id":"1",
     "start_end":[
	 "[2020-03-01T18:00Z TO 2020-03-01T23:00Z]"
     ]
    }
]

以下のクエリで2020年3月1日19時に営業している店舗を検索できます。

start_end:"2020-03-01T19:00:00Z"

DateRangeFieldを使うパターンだと営業時間を複数登録するのも簡単です。

[
    {
     "id":"2",
     "start_end":[
	 "[2020-03-01T11:00Z TO 2020-03-01T14:00Z]",
	 "[2020-03-01T18:00Z TO 2020-03-01T23:00Z]",
	 "[2020-03-02T18:00Z TO 2020-03-02T23:00Z]",
	 "[2020-03-04T11:00Z TO 2020-03-04T14:00Z]",
	 "[2020-03-04T18:00Z TO 2020-03-04T23:00Z]"
     ]
    }
]

クエリは先程と同じもので大丈夫です。

start_end:"2020-03-01T19:00:00Z"

DatePointFieldでstartとendの2つのフィールドを使うパターンだと、どうでしょう?
start と end を multiValued にしても解決しません。

[
    {
     "id":"10",
     "start":["2020-03-01T11:00Z","2020-03-01T18:00Z"],
     "end":["2020-03-01T14:00Z","2020-03-01T23:00Z"]
    }
]

と登録したとして、startのどちらがendのどちらに対応しているのかが検索時に区別できないからです。したがって、別のレコードに分けなければなりません。

[
    {
     "id":"10",
     "start":"2020-03-01T11:00Z",
     "end":"2020-03-01T14:00Z"
    },
    {
     "id":"11",
     "start":"2020-03-01T18:00Z",
     "end":"2020-03-01T23:00Z"
    }
]

営業時間だけを扱っている分にはこれでも良さそうに見えますが、他の店舗情報(店舗名、住所、電話番号等)もインデックスに含めるとすると、以下のどちらかを考えなければならなくなります。

  • すべてのレコードに店舗情報を含める(すごく冗長)
  • 店舗情報と営業時間情報を分けてJOINする(処理が複雑になる)

どちらにしても、DateRangeField を使った場合のシンプルさには比べるべくもありません。

検索時のオプション

インデックス側とクエリ側のどちらも時間範囲である場合、以下の5通りの組み合わせが考えられます。

  1. 全く重ならない(例: インデックス「1時から2時」クエリ「4時から5時」)
  2. 完全に一致する(例: インデックス「1時から2時」クエリ「4時から5時」)
  3. 一部分が重なる(例: インデックス「1時から2時」クエリ「1時半から3時」)
  4. インデックス側がクエリ側に含まれる(例: インデックス「1時から2時」クエリ「0時から3時」)
  5. クエリ側がインデックス側に含まれる(例: インデックス「1時から2時」クエリ「1時20分から1時40分」)

検索クエリとしてヒットしたかどうかの判定時に、1はヒットしない、2はヒットしたでいいのですが、3,4,5は要件によって判定を変えたいことがあります。そこで、以下のオプションが用意されています。

  • Intersects(デフォルト): 2,3,4,5がヒット
  • Within: 2,4がヒット
  • Contains: 2,5がヒット

と思ったら、8.4.0の実際の挙動は以下の通りでした。

  • Intersects(デフォルト): 2,3,4,5がヒット
  • Within: 4がヒット
  • Contains: 2,5がヒット

具体的には

[2020-03-01T01:00Z TO 2020-03-01T02:00Z]

というデータに対して

{!field f=dateRange op=Within}[2020-03-01T01:00:00Z TO 2020-03-01T02:00:00Z]

というクエリがヒットしませんでした。opがContainsやIntersectsならヒットしました。Withinの場合は両端のどちらかが一致しているとヒットにはならず、インデックス側が完全に内側に無いといけないようです。

おわりに

DateRangeFieldを使うと、幅の有る時間のデータをシンプルに取り扱うことができます。「日付データ→pdate」と短絡せず、要件に合わせて使い分けるようにしたいところです。


脱!コロナ太り!!ポップコーンダイエットをやってみた結果

こんにちわ。
リエです。

コロナウイルスの影響で外出自粛のいま、完全に運動不足の私です( ;∀;)
1日中お家の中にいるので(現在弊社はリモートワーク中)食べる事が楽しみの一つとなり、その結果太る太る(^q^)コロナ太りしました。
まぁ今はしょうがないよなと自分を甘やかしてきましたが、さずがにコレはないわと自分の身体を見て思ったのでダイエットする事にしました。

どんなダイエットがいいだろうと考えていたのですが、この記事を読んでポップコーンダイエットに決定。
■1食をポップコーンに置き換えるだけの『ポップコーンダイエット』にスタッフが挑戦!!結果は如何に!?【実施結果報告】
https://popcorn-papa.com/magazine/popcorn-labo/2020-03-13/12283/

今は外食もできないですし、ちょうどいいなと思いました。
何よりポップコーンパパのポップコーンが大好きだし💕

ポップコーンダイエットとは?

ポップコーンは食物繊維が豊富で低カロリーということで、1日のうちの1食をポップコーンに置き換える、いわゆる置き換えダイエット。
ただし、味は塩味のポップコーンに限る。(あまい系だとカロリーが高くなり、おつまみ系だと塩分が気になるため)

それでは実践

私は以下のようなルールで実践しました。
・期間は4日間で夜ご飯を塩バターポップコーンに置き換える。量は好きなだけ食べてもOK。
・朝・昼は通常通りの食事でOK。ただし間食は控える。(完全に我慢するのはつらいので、どうしても甘いものを食べたくなったら150キロカロリー未満で15時までなら食べてもよし!とする)
・夜ご飯は遅くても19時までに食べる。
・激しい運動はNGだが、10分〜15分軽いストレッチや筋トレを行う。

結果

結果はマイナス1キロでした✨
う、うれしい(´;ω;`)
私はとにかくお腹周りが気になっていたのですが、それもスッキリしました。
食べすぎて大きくなった胃も少し戻った感じもします。
ちなみに1食で食べたポップコーンの量ですが、ポップコーンパパのポップコーンレギュラーサイズ1袋です。
■ポップコーンパパ 塩バターレギュラー(1.2リットル)
https://www.popcornpapa.jp/shopdetail/003000000003/&category_code=ct2

これだけだとお腹が空いてつらそうかもと思ったので、飲み物は無糖炭酸水にしたのですが、いい感じにお腹が満たされました。
夜がポップコーンのみなので、次の日の朝ごはんは何食べようかと考えてる時間が幸せすぎました。
私は甘いものが大好きなのですが、どうしても食べたくなった時は間食でアイスボックスを食べていました。アイスボックスはカロリー13キロでほぼ氷なので罪悪感なく食べられてだいぶ助けられました。
朝とお昼は通常通りの食事でOKとしましたが、せっかく4日間頑張るので昼食は和食中心にして糖質を意識したのもよかったかも。

どうしてもお腹がすいちゃうとき

ある程度お腹が満たされても、なんせポップコーンのみ。
時間が立つとさすがにお腹が空いてちょっとくらいなにか食べてもいいかなという気持ちになりました(笑)。
そんな時はこんな事をやっていました。
・食べたらさっさと歯を磨く
・大食いYouTubeさんの動画を見る(自分の代わりに食べてもらってる気持ちになりなんか満たされる)
・寝てしまう

まとめ

ポップコーンダイエットですが、私は効果を感じました。
ただし1食置き換えとはいえ長期的にするのは健康にはよくないと思うので、
【短期間に増えた体重を落としたい】【ダイエット準備として胃を調整したい】方に向いているのかなと思います。
基本はバランスの取れた食事、適度な運動が大事だと思うので、落とした体重を維持できるよう引き続き意識した生活を送りたいと思います!