Java SE 8 Programmer II (1Z0-809:Java Gold)に合格しました

Java Goldに合格しました~
やった~

取得理由

去年、Java Silverは取得済み。
Java SE 8 Programmer I (1Z0-808:Java Silver)に合格しました - delateteiの日記
それ以降でJava案件を打診されるときには「Java Silver持ってますよ」とアピールするようにしていたんだけど、「なんでGoldじゃないの?」と決まって返される。ろくな技術者を集められてないのにマウンティングしてんじゃね~と思いつつも、まぁ確かにSilverってのも中途半端だなと思って取ることにした。


経験

社会人5年目。
Javaの経験は合わせて1年もない。

試験対策

黒本をやった。
思い立った2週間後(10/29)に試験予約をしたもののSilverが黒本一冊で楽勝だったのでナメて放置。直前の金曜日から本腰を入れて、とりあえず各章の練習問題は解けるようにした。が、巻末の模擬試験だと50%程度の正答率だったので模擬試験も解けるような状態にした。(この時点でWEBダウンロードできる模擬試験がもう一本あることを完全に忘れてる。)

本番

全然解けない。
黒本と同じような問題が多少出たので助かったものの、その場で考えてどうにかなる問題はほぼない。試験時間を使い果たして一応埋めはしたが半分ギブアップ状態。

結果

正答率:67% 合格ライン:65%でギリギリ合格。


やるべきだったこと

全くネットで様子を調べなかったんだけど、調べるべきだった。(WEBの模擬試験やってないから言い切れないけど)黒本だけだと十分じゃないと思う。英語だけど米Oracle社が出してる問題週とかいいんじゃないでしょうか。あと必ず出題される問題もあるっぽいのでチェックする(サマータイムを絡めた問題とか)。
あと試験範囲は広いけどラムダ式とストリームからの出題が多いので重点的にやったほうが良い気がする。(自分はここを結構抑えられていたので合格したのだと思う)

合格しての所感

Java Goldとは言いつつもSE8のGoldなのでJava全体に精通しているという感じはまったくしない。ましてや業務だとフレームワークを使うだろうからなぁ。。。
結局は下みたいな感想に落ち着く。

アフィリンク

楽天でチケットを買うと安いです。よろしくお願いします。

AudioProcessorValueTreeStateを使ったパラメータ管理 独自リスナー実装編

AudioProcessorValueTreeStateを使ってパラメータ管理が楽になった!最高!てな感じなんですが、パラメータの変更に連動して別の処理を呼びたい/値を変更したい場合があると思います。AudioProcessor::setParameterだとProcessor側のパラメータに値を設定するついでに好きな処理を書いておけば済む話ですが、AudioProcessorValueTreeStateでは?

AudioProcessorValueTreeStateは独自にリスナーを追加できるので実装します。

まずリスナーを定義。
AudioProcessorValueTreeState::Listenerを継承してparameterChangeをオーバーライドします。

// Processorの処理や値にアクセスするという想定でインナークラスを定義
class TestAudioProcessor  : public AudioProcessor
{
/* 中略 */
private:
    struct TestParameterListener : AudioProcessorValueTreeState::Listener
    {
    public:
        TestParameterListener(TestAudioProcessor& p);
        void parameterChanged(const String& parameterID, float newValue) override;
    private:
        TestAudioProcessor& _p;
    }
/* 中略 */
}

実装

// コンストラクタでアウタークラスのインスタンスをもらう
TestAudioProcessor::TestParameterListener::TestParameterListener(TestAudioProcessor & p)
    :_p(p)
{
}

// testMethodの呼び出し
void TestAudioProcessor::TestParameterListener::parameterChanged(const String & parameterID, float newValue)
{
    _p.testMethod(newValue);
}

Processorのコンストラクタとかで)AudioProcessorValueTreeStateのインスタンスにリスナーを追加します。

parameters.addParameterListener("test", new TestParameterListener(*this));

これでtestパラメータに連動して独自に定義したTestParameterListenerが呼び出されます。
やったね。

AudioProcessorValueTreeStateを使ったパラメータ管理

AudioProcessorValueTreeStateについて

JUCEでパラメータ管理を簡単に行うためのクラス。(多くの場合において)従来のAudioProcessorを用いた方法やAudioProcessorParameterを用いた方法よりコードが短く、分かりやすくなる。

公式のチュートリアルを読めば使い方は大体分かると思うので、個人的に補足したいところだけを好き勝手に書く。Tutorial: The AudioProcessorValueTreeState class | JUCE

従来の方法

AudioProcessorを用いた方法

手順としては大まかに以下のようになる。

  • AudioProcessorでパラメータ用の変数を定義
  • AudioProcessorでParameter系の関数を実装
  • PluginEditorでGUIコンポーネントを定義
  • GUIコンポーネントのイベント処理を実装
  • タイマー処理を実装
  • パラメータの保存/読込処理を実装

実装量が多く、AudioProcessorとPluginEditorでパラメータを二重管理するような形になる。ホストを介したPluginEditor→AudioProcessorのパラメータ変更通知も(必要があれば)自前で正規化しないといけない。そして、公式にてAudioProcessorのParameter系の関数は廃止予定とアナウンスあり。

AudioProcessorParameterを用いた方法

廃止される上記方法に取って代わる方法で、大分スマートになった。今回紹介するAudioProcessorValueTreeStateはAudioProcessorParameterのラッパーなので、用途に合わなければAudioProcessorParameterを継承したクラス(AudioParameterFloat等)を使って作り込むことになると思う。

AudioProcessorValueTreeStateを用いた方法

AudioProcessorでAudioProcessorValueTreeState::createAndAddParameterを呼び出してパラメータを追加する。あとはPluginEditorでGUIコンポーネントと先ほど追加したパラメータを連携させれば完了。連携したGUIコンポーネントはパラメータの範囲や初期値が設定されるので別途設定する必要はない。パラメータの保存/読込も一括で処理可能。

チュートリアルの補足

normalisableRange

createAndAddParameterの第4引数。値のレンジ(最小値・最大値・刻み幅)を指定する。[0,1]の範囲以外を設定しても問題なく、(必要がある箇所では)勝手に正規化される。

valueToTextFunction

createAndAddParameterの第6引数。(Cubaseで言う所の)一般エディタへ値をどう表示するかを設定できる。nullptrを渡した場合、[0,1]に正規化されて表示される。渡ってくるvalueは正規化されていない値なので、基本的にはreturn String(value);しておけば問題ないはず。

textToValueFunction

createAndAddParameterの第7引数。valueToTextFunctionの逆で数値がキーボードから入力された時に呼ばれるものだと思うんだけど、よく分からない。ブレークポイントを張ってデバッガをかけても止まらない。ちなみにキーボードからパラメータを入力しようとすると正規化されてしまって、入力した値がそのまま設定されないので非常に困る。だれか詳しい人教えて下さい。

Neko Guitars Claymoreのハードウェアを交換した

7弦ギターのペグ、ブリッジ、ノブを交換しました。

Neko Guitarsとは

海外の新興ギターメーカーです。
ヘッドレスとかブラックマシーンぽいやつとか、時流に乗った製品が多いです。
主にFacebook上で活動していますが、日本向けのTwitterもあります。
https://www.facebook.com/NekoGuitars/
twitter.com


日本市場へのサポートが手厚かったため、海外新興メーカーとしては珍しく国内に購入者が多いです。
Twitterで検索すれば多くの情報を手に入れることができます。

はい。

交換前

f:id:delatetei:20170527192355j:plain
f:id:delatetei:20170527193910j:plain
自分のClaymoreは1st Runモデルです。
ピックアップは白い韓国製のものでしたが、国産の千石ピックアップに交換済み。
ペグ、ブリッジは謎。精度はあまり良くないです。
2nd RunからはHipshotが標準搭載されています。

パーツについて

Hipshotがポン付けできます。

HipshotのGrip-LockはClosedタイプを選びます。
一般的にGrip-LockといえばOpenタイプだと思うので、気をつけたほうが良いです。
Openタイプはネジ位置が違うのでポン付けできません。
f:id:delatetei:20170527194724j:plain

交換する

黒色もつまらないのでゴールドパーツにしました。
Jacksonが好きな感性。。。
ただClaymoreはつや消し(サテンブラック)なので色味が合うか不安。

交換自体はポン付けなので困難はないです。
Hipshotのペグの方がネジが二回り大きいので、ネジ穴を適当にさらいます。
f:id:delatetei:20170527195118j:plain

交換後

f:id:delatetei:20170527195525j:plain
f:id:delatetei:20170527195529j:plain
まぁこんなもんですかねー。
Hipshotのゴールドは色味がかなり黄色いので、くすんでくると馴染むかな?


f:id:delatetei:20170527195532j:plain
おわり。

XEMのティッカーを投稿するTwitter BOTを作った

仮想通貨のNEM/XEMのティッカーを投稿するTwitter BOTを作りました。
ZaifからXEMのティッカー(終値、高値、安値、VWAP、出来高、売値、買値)を取得して10分毎に呟きます。

twitter.com
f:id:delatetei:20170423173747p:plain

NEM/XEMは急成長している仮想通貨です。
世間的な知名度はまだまだで、レートを見るにもわざわざ取引所にアクセスしないといけなかったりします。
そういうのが面倒くさかったので作りました。

完全に自分のために作ったものですが、フォロワー数も伸びてきているし、好意的な反応も頂けてよかったです。


技術的に語る所はまったくないです。
Zaifが公開しているJSONをパースして要素を取り出して投稿しているだけです。
技術的な困難さとコンテンツが有益かどうかは紐付かないと頭で分かっていても、こういうものを表に出すときは周りからどう思われているか分からなくて怖い。
でも、簡単なBotだったとしても、ネットに流れる情報が増えれば界隈も盛り上がるし、それで価格が上がれば良いかなという気持ちでリリースします。

ということで、よかったら見てやって下さい。

JUCE Frameworkを使ってディレイを作ってみた

手軽にVSTが作れるJUCE Frameworkを使ってディレイを作ってみました。
JUCE JAPANという入門書(良書!)を読んで始めたばかりなので、解説というか製作記のノリで書きます。

ソース

JUCEは手探り&C++は自信無い感じなのでソースを抜粋して載せます。

PluginProcessor.h

class DelayAudioProcessor  : public AudioProcessor
{
// 中略
private:
    int sampleNumPerDelayTime;
    int repeatNum;
    float delayTimeMiliSec;
    std::vector<boost::circular_buffer<float>> delayLine;
};

パラメータとしてメンバに以下を設定。

  • 1回ディレイするのに必要なサンプル数(sampleNumPerDelayTime)
  • 何回繰り返すか(repeatNum)
  • 何ミリ秒ディレイするか(delayTimeMiliSec)
  • ディレイ用のバッファ(delayLine)

ディレイは簡単に言ってしまえばバッファに音を詰め込んでそこから取り出すだけなので、データ構造として何を選ぶかがキモになります。
FIFOかつ決まった秒数のサンプル数を保持できればいいので、サーキュラーバッファ(リングバッファ)がよく選ばれるそうです。
素のC++だとサーキュラーバッファを扱えないので、別途Boostを入れます。
サイズの管理を自分でやるのであればstd::dequeとかでも良い気がします。
あとJUCEにはAudioBufferクラスっていうのが存在するみたいなので、それが一番いいのかもしれません(不勉強)。

バッファはチャンネル毎に必要なので、vectorに入れてみる。

余談:Boost

Boostはネットで拾ってきてうまいことコンパイルする。
自分は↓をみてやった。
programming-aip.blogspot.jp
コンパイルに関して、

Visual Studioコマンドプロンプトを開くか,普通のコマンドプロンプトを開いて64ビット版をビルドしたければ,"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"を実行する.

と書いてるけど、コンパイラへのパスが通っていないといけないので前者が良いと思う。
開発者コマンドプロンプトってやつです。

あとはProjucerでDebugやReleaseのHeader search pathsとExtra library search pathsにそれぞれのパスを設定すれば使える。

余談:DelayLine

DelayLineはプログラム的にはただのバッファなんだけど、アナログの世界だとほんとに線なので面白いです。
Analog delay line - Wikipedia

PluginProcessor.cpp

void DelayAudioProcessor::prepareToPlay (double sampleRate, int samplesPerBlock)
{
    sampleNumPerDelayTime = delayTimeMiliSec / 1000.0f * sampleRate;
    while (delayLine.size() < getTotalNumInputChannels())
    {
        delayLine.push_back(boost::circular_buffer<float>(sampleNumPerDelayTime * repeatNum));
    }
}

prepareToPlayでVSTホストの情報を使った初期化処理を書く。
sampleRateは単位秒ごとのサンプル数(44,100とか)なので遅延時間を掛けると確保すべきバッファ長が分かります。
更に繰り返し回数を掛けてバッファを確保する。

void DelayAudioProcessor::processBlock (AudioSampleBuffer& buffer, MidiBuffer& midiMessages)
{
    const int totalNumInputChannels  = getTotalNumInputChannels();
    const int totalNumOutputChannels = getTotalNumOutputChannels();

    for (int i = totalNumInputChannels; i < totalNumOutputChannels; ++i)
    {
        buffer.clear (i, 0, buffer.getNumSamples());
    }

    for (int channel = 0; channel < totalNumInputChannels; ++channel)
    {
        float* channelData = buffer.getWritePointer (channel);
        for (long buffNum = 0; buffNum < buffer.getNumSamples(); buffNum++)
        {
            delayLine[channel].push_front(channelData[buffNum]);
            for (int i = 1; i <= repeatNum; i++)
            {
                if(delayLine[channel].size() < sampleNumPerDelayTime * i) break;
                channelData[buffNum] += (0.5f / i) * delayLine[channel][sampleNumPerDelayTime * i - 1];
            }
        }
    }
}

一番深いネストの部分がディレイの部分。
(クラスを作ったほうが良いという意見も当然あると思うけど、短かったので。。。)

push_frontでサンプルをバッファに入れているので、begin側が新しいサンプル、end側が過去のサンプルになります。
例として、遅延時間を1秒、繰り返し回数を3回、サンプリングレートを44,100とすると、バッファの中身は以下の様になります。
delayLine[channel][44099] :1秒前のサンプル
delayLine[channel][88199] :2秒前のサンプル
delayLine[channel][132299]:3秒前のサンプル
なのでこれらを原音に足し込んでいくとディレイするようになります。

足し込む際の減衰はボリュームカーブの実装をちゃんと考えないといけないです。
さすがにコレ(0.5f/i)は適当すぎる。
ちゃん作り込むとなると、繰り返し回数が全部聞こえるようにカーブを設定しないといけないと思う。

サンプル

鳴らしてみるとこんな感じになります。

参考

JUCE JAPAN vol.1: JUCEではじめるVST/AUプラグイン制作(Windows/MacOS対応)

JUCE JAPAN vol.1: JUCEではじめるVST/AUプラグイン制作(Windows/MacOS対応)

www39.atwiki.jp


またなにか作ったら書きます。

2016年のまとめと2017年のこと

セーフなうちに書きましょう。

仕事

新卒で3年と少し(40ヶ月)勤めた会社を辞めました。
所謂ブラックだったので辞めるのにも一苦労、といった感じでしたが、懇意にしてもらっていた上司に連れられる形で脱出しました。
ひとまずは落ち着いた環境で過ごせています。
腰掛けというと言葉が悪いですが、自分がやりたいことをやれるようになるまで預かるだけだからなと上司からも念を押されているので、独り立ちできるように準備中です。

プライベート

プロダクト

自分の時間が持てるようになったこともあり、いくつか作りました。

デジマート中古ギターアーカイブ

デジマート中古ギターアーカイブというサイトを作りました。
f:id:delatetei:20170106211052p:plain
国内最大の楽器検索サイトであるデジマートに登録された中古ギターの情報を保存しています。
半端ない数のギターがデジマートを介して取引されているのですが、商品が売れたら商品ページが削除されてしまうため、貴重な情報があっという間に失われてしまいます。それを惜しく思ったので作成。

検索機能がメインですが、ウリとして魚拓代わりのスクリーンショットを取得しています。


技術的な話を以下つらつら。

・サーバー構築
VPSを借りて一からやった。
ウェブ系はからっきしなので外向けのサーバ構築はだいぶ骨が折れた。
でも勉強になった。

・サイト
RoRに初挑戦。サクサク作れて楽しい。

・クローラ
Rubyによるクローラー開発技法」を片手にRubyで書いた。
時間帯によるアクセス頻度の調整はcronから呼ぶシェルでうまいことやってます。

スクリーンショットの取得
PhantomJSで取得。
動作時に読み込ませるjsファイルはperlでガリガリ自動生成した。
その後はpngquantで圧縮。

デジマート中古ギターアーカイブ(TwitterBot)

デジマート新着中古ギター情報
f:id:delatetei:20170106214636p:plain
上記サイトでスクレイピングした情報をついでにTwitterBot投稿。
“おまけ”のつもりだったのですが、明らかにこっちの方が利用者が多いです。
(フォロワー約1,200人)

たまに面白いギターが登録されると、RTで自分にも回ってきたりします。
こういうのとか


中古楽器入荷速報

f:id:delatetei:20170106222814p:plain
楽天に登録された中古楽器の情報を流すBot
楽天アフィとAPIで小銭稼ぎできないかな~と思って作った。
Twitterに直接アフィURLを貼ると短縮URLに変換されて規約違反になるので、自前のWordpressに誘導するという酷いユーザーエクスペリエンス。
毎月1,000~2,000円程度は稼いでくるので、VPS代は賄えている。と思う。

一応、本気でアフィをやってみた感想として、自分の性格に合わない、投入労力に見合わないというのが分かったのが収穫。
これでアフィに未練はないです。

その他

投資を始めました。

ブラック企業時代は
仕事でストレスを受ける→金遣いが荒くなる→貯金がないから辞めるに辞めれない
という酷いループに陥っていました。
最終的に一文無しで転職することになって苦労したので、貯金がてら投資信託をやっています。

また、夏を過ぎた頃から日経平均の地合いも良くなっていたので、少額で個別株を買って勉強したりもしています。

元本が少ないので儲けも微々たるものですが、お金の入り口が増えることによる精神的な安心は思ったより大きいです。
(当然、リスクもありますが)お金のない人こそ投資の勉強をしてもいいんじゃないかなって思います。

まとめ

転職や投資の勉強をしたことによって自分の時間が作れるようになったので、2017年はどんどんモノ作りしていきたいと思います。
ブログもちゃんと書きます!

それではよろしくお願いします~