読者です 読者をやめる 読者になる 読者になる

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

VST C++ JUCE

手軽に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年はどんどんモノ作りしていきたいと思います。
ブログもちゃんと書きます!

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

Java SE 8 Programmer I (1Z0-808:Java Silver)に合格しました

Java

Java Silverに合格したので所感を述べます。

受験のきっかけ

Javaでの開発経験を信用してもらえなかったから

IT土方としてプロパーさんと面談する際、技術的な話はあまり聞いてもらえない。
SI業界だと人売りが経歴を盛ることも珍しくないから、年齢が若いとコミュニケーション能力があるかどうかに話が行きがち。
開発経験を口だけで語っても胡散臭く思われるだけなので資格取得を決めた。

ざっくりした経歴

社会人4年目。
C on Vim on Unix(Linux)で制御系の開発をやってた。
実務でのJavaはSwingをちょこっと触ったことがある程度。

勉強時間

40時間ぐらい。

教材

いわゆる紫本と黒本。
最初は紫本だけで臨もうとしていたけど、念のために黒本を買ってみたら全然解けなくて大慌て。

黒本は問題が良く出来ていて、理解が甘い所をピンポイントで突いてくるからすごく勉強になった。
ほとんど同じ問題が実際の試験でも出題されるので、進研ゼミ状態。

紫本は本としての質がそもそも低いと思った。
出題範囲についてざっくりとは分かるだろうけど、本質的に理解ができるかというと???
amazonでも概ね評価が良いように見えるが、“赤点ギリギリだけど試験に合格できたから星5つ”みたいなレビューが多い時点でお察し。
Javaを触ったことがないような人だといいかも知れない。それでも黒本と併用したほうがいいと思う。

分厚い本を何周もする気になれなかったし、手応えがあったから各々一周読んで受験した。

受験の申し込み

  • Oracleのページ分かり辛い
  • ピアソンのページも分かり辛い

チケットは楽天で買ったほうが(2000円ぐらい)安いです。
ピアソン的には試験会場の予約と同時に買わせたいみたいで、試験を選択した時点で正規の金額が画面に表示されます。
ページを進めていくとバウチャーを入力する箇所があるので、買ったチケットのコードを入力すれば問題なし。
金額が差し引かれるのでピアソンでもお金を払うようなことにはなりません。
下はアフィリンク

試験会場の話

  • ベンダー資格は受けたことがなくて、テストセンターでの受験も初めてだったから緊張
  • 電子署名したり顔写真をwebカメラで取られたりハイテク
  • 椅子が想像より低かったせいで座る際に受験スペースで転けそうになる

試験中の話

  • 難易度は黒本より低い
  • 手応えはあったけど、受験料が高いこともあって結構プレッシャー
  • イヤーマフをつけると周りの音が聞こえない代わりに自分の心音が聞こえるから焦ってるのが分かって微妙
  • ホワイトボードは渡されるけど、イレイサーはない。書きっぱなし。
  • 渡されたペンのインクの出が悪くてイライラ
  • PC画面を見ながら問題を解くのは疲れる
  • インデントがおかしい問題があって???
  • 全問解いた時点で30分残っていたけど、気力が残っていなかったのでとっとと退出

受験後の話

  • 採点結果は試験終了から7分程度ですぐ来た
  • 正解率94%で合格

これから

本当はC++案件やりたい

Ruby on Railsでransackを使った単一カラムに対する複数キーワードでの検索

Ruby

勉強中のRailsで少し躓いたのでメモ。

www.imd-net.com
上記の記事を参考に検索機能を実装し、単一カラムに対して複数キーワードでの検索を行いたい。
参考記事内で“複数条件での部分一致”という言葉が出てくるが、それは「複数カラムに対して単一キーワードでの検索」で今回実装したい機能とは逆なので注意する。


まず、検索条件に合うname値をGitHubのransackから調べる。
ORの場合はcont_any (contains any)
ANDの場合はcont_all (contains all)

サンプルとして、descriptionに対してAND検索してみる。
参考記事内のapp/views/products/index.html.erbを以下のように書き換える。(15~18行目)

<div class="form-group">
  <%= f.label :description_cont_all %>
  <%= f.text_field :description_cont_all, class: "form-control", placeholder: "部分一致" %>
<div>

例えばこの状態でフォームに「hoge piyo」と入力して検索を実行すると、controllerにparams[:q]として以下のハッシュが渡る。
{"description_cont_all" => 'hoge piyo' }

上記のハッシュをransackに投げても、ハッシュの値である「スペースを含めた文字列」での検索が行われてしまうので、スペースで分割してハッシュの値を配列にする。
app/controllers/products_controller.rbを以下のようにする。

def index
  condition = Hash.new
  if params[:q].kind_of?(Hash)
    params[:q].each do |key, value|
      if key == 'title_cont_all' then
        condition[key] = value.split
      else
        condition[key] = value
      end
    end
  end
  @q = Item.ransack(condition)
  @items = @q.result
end


冗長な書き方になっているので、実際のところはハッシュをMarshalでディープコピーしてそれを書き換えた方がいいのかなって思います。

Misha Mansoor(Periphery)の使用機材

2月に公開された動画に写っているMisha Mansoor(Bulb)の機材を紹介。


Misha Mansoor&#39;s Guitar Recording Tips - YouTube

ギター

Jackson Custom Shop / 6 String

 

ピックアップ

Bareknuckle / Juggernaut Pickups

 

アンプシミュレーター

Fractal Audio / AxeFX II

XLじゃない方。

マイナーチェンジのMARK II版。

オーディオインターフェース

Focusrite / Scarlett 2i4

DAW

Steinberg / Cubase 6

DAWの定番。

現行が7.5なので少し前のやつですね。

キャビネット&マイキングシミュレーター(ロードボックス)

TWO NOTES / Torpedo Live

シンセサイザー

Waldorf / Blofeld Keyboard

電源

Furman/PF-PRO Power Factor Power Conditioner Rack

珍しいモデルなのか、あまり情報なし。。。

Furman自体は有名ですね。

これのラックじゃないやつはよく使われてるのを見ます。

チューブDIBOX

Palmer / PDICTC Tube DI Box

マイク

SHURE / SM57

マイクプリアンプ

FOCUSRITE / ISA430 mkII

モニターコントローラー

Mackie / Big Knob
【モニターセレクター】●MACKIE Big Knob

【モニターセレクター】●MACKIE Big Knob
価格:37,800円(税込、送料込)

ヘッドフォン

ULTRASONE / PRO900

モニタースピーカー

EVENT / OPAL

検索してもあんまり日本語の記事が見当たらないですが、評判はいいみたいです。

国内だとSoundhouseでしか売ってないのかな…?

 

総括

良い機材が多い!