BoseとAirPods Proのノイズキャンセル性能を踏まえて比較

ノイズキャンセル性能はBoseに比べて一段劣るが、それに対して目をつぶっても良いほどに最高のイヤホンでした。

独立型

Boseのノイズキャンセルはネック型になっているのが難点で、ノイズキャンセルしたいシーンでも付けるのが面倒臭いので我慢するといったこともあったが、AirPods Proなら簡単に付けられるので、その点のストレスがないことが非常に良い。

布団で寝ながらつけられるのもいい。ネック型だと首が痛くてつけられない。

ハードウェアからモード切り替えできるのが良い

Boseのイヤホンの場合はスマホのアプリから外部音取り込みをきりかえたりする必要があるので、誰かに話しかけられたり、話しかける時は、いちいちアプリ操作したくないので、イヤホン自体をはずすような運用をしていたが、AirPods Proならボタンを長押しするだけで即時切り替えられるので、そのストレスもない。

Androidだとファームウェアアップデートができない

BoseはAndroidでもファームウェアアップデートのようなことができるが、AirPods ProはApple製品だけを対象としているので、接続したらAirPods Proの情報が分かるみたいなこともないし、ファームウェアアップデートもApple製品に接続しないとできないらしい。

Androidでも制御できるアプリ的なものを出すことはできると思うので出してほしい。イヤホンそのものはBose超えを果たしていると思うんだよね。だからApple製品だけでしか使えない感じにするのはもったいなすぎる。

おわり

個人的にAppleアンチなのですが、今世界で一番最高のイヤホンはAirPods Proで決定かなと思いました。

AirPods ProをAndroidで使う方法

ペアリング

screenshot

ケースのボタンを長押しするだけでよい。で、AndroidならAirBatteryを使いたい。

ノイズキャンセルモードと外部音取り込みモードの切り替え

イヤホンのボタンを長押しすることで切り替えられる。このボタンで音楽の再生・停止・スキップもできるようになっており何ら問題はない。

ファームウェアアップデート

ファームウェアアップデートはApple製品がないとできないらしい。iPadがあればそれでいいかもしれない。iPadは良いぞ、テレビを捨ててiPadにすると良い。

おわり

Androidでも全然使える。

RustでJSONをStructにパースする

単なる平らなオブジェクトなら最悪並べていけばいいですけど、複雑な構造の場合は結構面倒です。この点はserde_drive::Deserializeを使えば結構スムーズにパースできるようです。試してみます。

まず、Cargo.toml はこんな感じ

[dependencies]
serde = "1.0.*"
serde_json = "1.0.*"
serde_derive = "1.0.*"

コードはこんな感じ

use serde_derive::Deserialize;

fn main() {
    let json = r#"{"name":"taro","age":20,"hobby":{"name":"game"}}"#;

    #[derive(Debug, Deserialize, PartialEq)]
    struct Human {
        name: String,
        age: u8,
        hobby: Option<Hobby>,
    }

    #[derive(Debug, Deserialize, PartialEq)]
    struct Hobby {
        name: String,
    }

    assert_eq!(
        serde_json::from_str::<Human>(&json).unwrap(),
        Human {
            name: "taro".into(),
            age: 20,
            hobby: Some(Hobby {
                name: "game".into()
            })
        }
    );
}

これでどんなJSONでもどんとこいですね

Rustでmd5を生成する

cargo add md5 して、今回は0.7.0が入ったな

let digest = format!("{:x}", md5::compute(b"test"));
assert_eq!(&digest, &"098f6bcd4621d373cade4e832627b4f6");

最近寒いですな

2019年の振り返りと2020年の抱負

こういうの書いておくと後で思い出になるし、糧にもなるので。

2019年の振り返り

  1. 本業が忙しい
    • 今回は本業が忙しくさすがに転職を考えるわけです。まあでも、大変なのは今だけだし、勉強になるし、他の仕事より楽ちんで答えも明確だから、続けなくてはと思った一年でした。
  2. 病気をきっかけに生活習慣の見直し
    • 全身ボロボロな件に気づいて生活瞬間を見直しました。運動して、酒や食事に気をつけています。
  3. Youtuberをはじめた
    • やりたいテーマがあったのでやってます。泣かず飛ばず。
  4. ブログを定量で書き始めた
    • 良い刺激になり休日や夜寝る前に勉強するきっかけになった。
  5. Webサービス花咲いた
    • 2年前くらいから運営したサービスが結構人気になってきた。泣かず飛ばずだったんだけど、時間が経ったら花咲くもんですね。
  6. 在宅勤務はじめた
    • 人とのコミュニケーションや自己管理が大変で、特に私はメンタルがやられます。だからといって前時代的な働き方に戻すのも芸がないので、この働き方でうまくやる方法を見つけたい。

2020年の抱負

  1. 本業を楽にこなせるように強くなりたい
    • 要量・技術・メンタルの3つを強化すればもう少し高いレベルの業務も淡々とこなせるだろう。
  2. Youtuberの継続
    • 強化はちょっと厳しい。今の強度の継続で数年は凌ぐ。
  3. Webサービスを作る
    • これは楽しいだけ。開発速度・運用コスパ・メンテのしやすさを両立できるRustで作りたい。

Rustでtokio-timerのIntervalを使って定期処理を行う

JSのwindow.setIntervalみたいなことがしたい。tokio-timerを使うといいらしい。で、tokioは現在2.4が最新なんだけど、結構古いシステムなので古いtokioで今回はやっています。

tokio = "0.1"
tokio-timer = "0.2.12"

take(10)ってところで10回処理するって設定なんですが、これを取ると無限に実行されます。

use tokio::prelude::*;
use tokio::timer::Interval;
use std::time::{Duration, Instant};

fn main() {
    tokio::run(
        Interval::new(Instant::now(), Duration::new(1, 0))
            .take(10)
            .for_each(|instant| {
                println!("ヒャロー! instant={:?}", instant);
                Ok(())
            })
            .map_err(|e| panic!("ぐああああ; err={:?}", e)),
    );
}

参考

https://tokio.rs/docs/going-deeper/timers/

RustのFutureでinspect_errでエラーの時に処理を行う

Futureが解決された時にエラーであればinspect_errの部分が実行される

use futures::future::TryFutureExt;

#[tokio::main]
async fn main() {
    assert!(async {
        Err::<(), String>("hoge".into())
    }.inspect_err(|e| {
        println!("{}", e)
    }).await.is_err());
}

try-cache的な感じの働きができるなーと思いました

   Compiling result v0.1.0 (/home/user/dev/rust/inspect_err)
    Finished dev [unoptimized + debuginfo] target(s) in 2.03s
     Running `target/debug/inspect_err`
hoge