20210206 ガーラ湯沢
ハロートナミです。スノボ行きました。
緊急事態宣言下なので出来るだけ密にならない事を意識し、電車と新幹線だけで辿り着け、かつ、道中一切話さずにいられるガーラ湯沢を選択。
車でやってきたオタクと現地で合流し、2人でのんびり滑りました。
(左がトナミ)
リフトなどで話すと距離が近いのでちょっとどうかと思いましたが
これ以上通気性の良い場所も無いと思うので、まあ大丈夫かなという判断です。
綺麗ですね。
気温は大体5~7度?で、インナー+ミドルウェア+ウェアだと暑かったです。インナーとウェアだけで良かった。
今シーズン初なので様子を見ながら滑り、まあなんとなく滑れるなという感じでした。
山頂のパノラマ写真。綺麗ですね。左にモンスターが写ってる。
出来るだけ色んなコースを滑ってガーラ湯沢の事が大体分かってきました。
アクセスは100点満点なのですが、コースは短いのが多く、あんまり面白くありません。
これはハヤシライス。
お昼を食べる頃には、ガーラはもう良いのでは?みたいな話になり
食後すぐにリフト券を3山共通にグレードアップして石打丸山へ向かいました。
写真無いのですが、石打丸山と接続するコースに小さめのパークがあって、そこはちょっと好きな感じでした。
ここから石打丸山。
石打丸山の6連リフト。すんげー。
これ降りるところで大混乱になったりしないのかな。
シートがふかふかしてるしヒーター入ってて温かいです。
石打丸山移動して滑り始めましたが、何度か滑ってたら普通に疲れてきて割と早めに撤退しました。多分15時ぐらいに終わったのかな。
ゲレンデとしては石打丸山の方が全然大きいし、楽しいです。
ただどちらもアクセスが良いので人が多くなっちゃうのが玉に瑕。
オタクバック
片付け中。今シーズンからの相棒November artiste。
前の板より硬くなったのでスピードを出した時の安定感が全然違いました。
本当はもっとガンガン乗るつもりだったのに、緊急事態宣言等のせいで全然乗れず寂しいです。
久しぶりのスノーボードでしたが、何とか普通に滑れることが分かったし
改めて180とかオーリー、小さめのキッカーを練習したくなりました。
あと2回ぐらい行けると良いですが、緊急事態宣言とどう付き合うか難しいです。
シーズンスポーツだからと言い訳して1回行きましたが、もう1度行っても許されるものなのか
今年はこれでもう終わりかもしれない。寂しいですね。おしまい
生活と新しいギター
ハロートナミです。これは日記です。
自分用アプリ開発は一段落して、不満を抱えつつメトロノームとして使っています。
今弾いているフレーズを自分はどれぐらいの速さで弾けるのか?とか確認するのに便利です。
ただ、精度はまだちょっと難があるので
固定BPMで弾き続けたい時は精度の良い別製品を使っています。
精度改善して自作メトロノームする事を目論んでいはいますが
こうしてみようという案すら固まっていません。頑張らないといけません。
生活
相変わらず殆ど家から出ない生活を送っています……と言いたいところですが
会社が週3テレワークになったので、週2回程出社で出歩いています。
フロアの人やチームの人と出来るだけ出社人数が増えないよう調整しているので
出社しても基本誰とも喋らず、1人で仕事して帰ってくるだけです。
一体何の意味があるのか謎です。
コロナ騒動に関して、うちの会社おかしくない?経営陣判断謎じゃない?みたいな事が多いです。
おちんぎんも良いとは思えないし、早めに出ていきたいですが
Findy氏からロースキル認定されてていまいち転職モチベが上がりきりません。ンー
4月ぐらいにジョブチェンジ出来てると嬉しいですね。頑張りましょう。
ギター
買いました。
ンカッコィーw
11月に買ったバングドリギターも自分には十分過ぎるギターだったんですが
せっかくのアニメコラボアイテムを傷だらけにしたくなかったのと
もともとアベフトシが好きなので、ぼんやりとテレキャスとテレカスに憧れがあり
メルカリ見てたら安いの流れてきて衝動買しました。
売上金使ったので実質出費は1万円ぐらいです。
ギター全然分からないので買ってすぐお店で見てもらって、市場流通ならもっと高い個体だよとお墨付きを頂きました。やったね
ちなみに、まだまだ全然弾けません。
地獄のメカニカルトレーニングの最初のフレーズを延々やっています。
早く友達とバングドリ合わせしたいです…。
運動
年末からずっと体調をぶち壊していたので、ずっと何もしてませんでした。
先日3km走ったら瀕死になったのでだいぶ貧弱な身体に戻ったようです。
またジョギングを頑張っていきたいです。
今年はまだ一回もスノボに行ってません。雪良さそうなのに。
シーズンスポーツをワンシーズン逃すとそのままフェードアウトしそうで怖いので
一回でも良いから絶対行くと決めています。
多分1人で新幹線でガーラかな。もしかしたら近場に居る人が来るかもですが
現地集合現地解散で、飯も別々に食べる事でしょう。
読書
最後に読んだ(でる)本並べます。
コンピュータサイエンスの基礎をやろうとだいぶ前に買っていて、最近ふと思い出して読んでいます。
ネットワークの仕組みについて基礎の基礎から学ぶ事が出来ます。まだ読み中ですがかなり良いです。
自分みたいなコンピュータサイエンス不勉強エンジニアは必読な気がします。
スタートアップ企業を題材にした漫画。熱め。まっすぐ頑張って結果を出すシンプルなストーリーですが、考え方やセリフが好きな感じでした。
ただ、今の所軌道に乗ったスタートアップの話が多いので、現実はそんな甘くないよなーみたいな事を思ってしまいます。
今後そのへんにも触れてくと思うので楽しみです。
あまりにも凄すぎる。人生で衝撃を受けた漫画TOP10に入ってきた。何も言う事が出来ない。
www.shonenjump.com凄すぎて好きなコマのTシャツ買ってしまいました。オタク
ゲームにしろ楽器にしろ仕事にしろ、自分は何をしてても練習して上手くなる過程が好きです。
ツイッテレでオススメされていて、学習に対する考え方について言及されており
自分の考えを整理する意味でも読んでみたいと思って買いました。
まだ読んでないですが楽しみです。
最近触った本はこのあたりですね。あとはまあApexしたりドーナドーナやったりしてのんびり過ごしていました。次の更新までにはもうちょっと書く事があるといいですね。おわり
続 Flutterで書いたメトロノームの精度を高める
ハトナミ。
th.hatenablog.jp前回に引き続きやっていきます。
とりあえず、音が鳴る瞬間のDateTimeを観測しました。
I/flutter (24608): 2021-01-17 10:03:23.019920
I/flutter (24608): 2021-01-17 10:03:23.523110 + 503190
I/flutter (24608): 2021-01-17 10:03:24.025354 + 502244
I/flutter (24608): 2021-01-17 10:03:24.527632 + 502278
I/flutter (24608): 2021-01-17 10:03:25.030974 + 503342
I/flutter (24608): 2021-01-17 10:03:25.533099 + 502125
I/flutter (24608): 2021-01-17 10:03:26.037653 + 504554
右のプラスは手計算した差分です。
BPMは120に設定しているので、ここが500000からズレている分だけ想定値とズレています。
やはり安定しておらず、常に遅れている状態なようです。
遅れ具合もまばらです。これを均していきましょう。
色々なマサカリがきているのですが、今回は1つ試した結果を書きます。
while(true)をやめる
こんなマサカリがありました。
https://twitter.com/sirrow/status/1348493240538787842?s=20
htt
://twitter.com/sirrow/status/1348493240
音を鳴らすところを await してるように見えるんだけど、こんな難しいことしないで、単純に javascript の setInterval とか使うインターバルタイマか、あるいはそれを薄くラップしただけの flutter のインタフェース叩けばいいのでは
オッケイ!やってみましょう。
dartはjsの代替を目指して設計されたらしいので、jsのアレコレに対して互換性があるとは思うのですが
Flutterでモバイル開発をしてる限りではjsの存在を感じる事が殆ど無く
どのような関係になってるか具体的なイメージが湧いていません。勉強しないとですね
インターバルタイマについて考えましょう。
繰り返し処理させる君はdartにおいてはTimerでやるっぽいので、とりあえず試してみます。
/// Timerで繰り返し処理する用の音源再生くん void _beat(Soundpool pool, int soundId, Timer t) { print(DateTime.now().difference(check).inMicroseconds); // 計測用 check = DateTime.now(); // 計測のために関数外で定義したDateTime if(!_run) {t.cancel();} pool.play(soundId); }
(差分を手計算するのが面倒だったので、計算してから出力するようにしました。)
とりあえずこんな感じの関数を生やして
var duration = Duration(microseconds: (60000000 ~/ _tempo)); // _tempo = 120; Timer.periodic(duration, (Timer t) => _beat(beatPool, beat, t));
こう書くだけで、Duration毎に音を鳴らして、前回実行時との間隔を出力してくれます。
超簡単。これ使えばwhile使ってごちゃごちゃ書いてたのがスッキリしそうですね。
動かしてみた結果、printの出力と録音した波形はこんな感じでした。
I/flutter (25379): 499513
I/flutter (25379): 500720
I/flutter (25379): 499491
I/flutter (25379): 498867
I/flutter (25379): 500159
I/flutter (25379): 500759
I/flutter (25379): 499186
げ、劇的に改善してる……。マジか。
という訳で、whileループをやめてTimerの繰り返し処理で動くよう修正しました。
github.comコミット8f7bf782bc74401559bc267c47745e2363e473c2でガーッと修正しています。
単純なループ処理は簡単だったのですが、ループ→転換処理→ループ……をうまく書けず
TimerがTimerを起動して無限にぐるぐる回る感じの実装をしました。
とっ散らかり感が凄いです。
とりあえずこれでも動いてはいますが、もっと良い書き方が絶対ありそう。
波形はこんな感じになりました。
前のよりはかなり良い……けど、やっぱり基準に対して微妙に前後していますね。
今まで起きていただんだん遅くなっていく = そもそもテンポがズレている。という問題は解消したのですが
音源再生のタイミングが微妙に前後してるのが直ってません。
人間が聞いて違和感があるぐらいにはズレてるので、まだまだ使用感は微妙です。
もう少し何とかしたいので、頂いたマサカリをもとに何が出来るか考えてみます。
そりでは
5
これは38787842?s=20
Flutterで書いたメトロノームの精度を高める
ハロートナミです。
th.hatenablog.jpについてです。
有り難い事に先日記事をあげたあと、すぐにIT強人(つよんちゅ)からいっぱいマサカリが来ました。ウハウハです。
自分より賢い人に指摘もらうの本当に最高で良い気分です。
頂いたマサカリをもとにもうちょっと精度なんとかならんの?をやっていきます。
現状の問題点
BPM120の設定で録音したデータをBPM120のDAW編集画面に貼っつけた状態です。
濃い縦線と波形が一致している必要がありますが、明らかにだんだんズレていっています。
これを出来るだけピッタリにしましょう。という作業をやります。
音源の再生時間を考慮する
while(_run) { waitTime = 60000 ~/ _tempo; // ここで拍の間の時間を定義 beatPool.play(beat); setState(() => _remainBeat = _remainBeat - 1); await Future.delayed(Duration(milliseconds: waitTime)); // 時間分待機
・・・
まず、メトロノームの拍として使ってる音源の再生時間がDurationに入っとらんやんけ。
という当然のツッコミが入ります。そりゃそうだ。
実装中は、音源を管理するSoundオブジェクトみたいなのを想定していて
そいつから音源の長さを取って、その分差っ引いて……と考えていたんですが
そんなオブジェクトは(自分で作らないと)無いので、面倒になってサボった箇所でした。
頂いたアドバイスがいくつかあったのですが
とりあえず再生前後の時刻を取得して再生時間を計算するようにしてみました。
///音を再生し、再生にかかった時間をmillisecで返す。 Future<int> playSound(Soundpool pool, int soundId) async { final lastTime = DateTime.now(); await pool.play(soundId); return DateTime.now().difference(lastTime).inMilliseconds; }
という感じで再生時間を出してます。
これだけで大分良くなりました。最初と比べるとかなり改善してます。
(上が最初のです。音の大きさは録音環境のせいで変わりました。)
かなり良いんですが、それでも少しずつ遅れていきます。
多少前後するけどかなり合ってますね。
んん、君もしかしてBPMズレてない?
BPMのズレを確認する
赤枠のがDAWの設定値です。
120で録音したものと119で録音したものを並べていますが、120の方がBPM119とぴったりですね。何ででしょう。
BPMを改めて手計算してからソースコードを見直して、まず気付いたのはミリ秒では精度が足りないのでは?という事です。
例えばBPM120の時拍子の間は500msで、BPM119だと504.2です。
今のソースコードだと小数点以下は切り捨てられてしまうので、これは悪影響がありそうです。
という訳で単純に値を全て1000倍して、使う単位をマイクロ秒に更新しました。
dartのDateTime及びDurationはmicrosecondsに対応しているため、ぱぱっと更新するだけです。
soundLength = await playSound(beatPool, beat); setState(() => _remainBeat = max(_remainBeat - 1, 0)); await Future.delayed(Duration(microseconds: (60000000 ~/ _tempo) - soundLength));
とりあえず感が凄いですが、これで精度の問題は解消とします。
……ですが、BPMのブレはあまり改善しませんでした。原因は他にあるようです。
今後
とりあえず書いた分で1エントリにしたいのでここで一旦終わりますが
何とか精度を上げて良い感じに使えるようにしたいです。
今気になってるのは
- そも、whileループってそんなに安定して動くの?
- 音源再生時間を取得するための処理にかかる時間が気になる。
の2つです。
BPMが1ずれてた問題についてはまだ良く分かりませんが
精度が悪いのがたまたまBPM1分のズレとして観測出来ただけなんじゃないかなーという気もしています。
あと、これと合っていればOKという参考が手元になくてだるいので
やる気が出たら物理メトロノームを買おうかなと思います。がんばっていきましょう