クラウド型VSTの試作

ヤマハの発表によると今後はクラウド型VSTなのだそうです。本当にそんなことができるのでしょうか。ならば作って試してみようと思います。

さて、何をもってクラウドVSTと言うかは微妙ですが、とりあえずインターネット上のサーバとやりとりできれば良いような気がします。なのでまずはVSTから簡単なWeb APIを叩くプログラムを作ってみることにします。

お題は例によって拙作ミク語変換API。漢字かな混じりの歌詞を読みがなに変換します。これがVST化されると何が良いのかは僕にもわかりません。
 
VSTを作るには、スタインバーグのサイトデベロッパー登録してSDKをダウンロードします。
あたりまえですが、SDKには通信APIなんてないのでWin32 APIを叩く関数を自作します。
ていうか、テキストエリアの部品もないのか。これも自作。
 
できた。

 
画面表示と通信をおこなうエディタ部のコードはこんな感じです。
editor.cpp

#include <windows.h>
#include <wininet.h>
#include <stdio.h>
#include "editor.h"

// エディタ画面
Editor::Editor (AudioEffect *effect): AEffGUIEditor (effect)
{
    rect.left   = 0;
    rect.top    = 0;
    rect.right  = 550;
    rect.bottom = 300;
    effect->setEditor (this);
}

Editor::~Editor()
{
}

void Editor::idle()
{
    AEffGUIEditor::idle();
}

bool Editor::open (void *ptr)
{
    frame=0;
    AEffGUIEditor::open (ptr);

    CRect rct(0, 0, 550, 300);
    frame = new CFrame(rct, ptr, this);
    frame->setBackgroundColor(kGreyCColor);

    CRect size(0, 0, 230, 280);
    size.offset(10, 10);
    inArea = new CTextArea(size, k3DOut);
    frame->addView(inArea);

    size (0, 0, 50, 20);
    size.offset (250, 130);
    frame->addView (new CTextButton (size, this, 'Conv', "Convert!"));

    size(0, 0, 230, 280);
    size.offset(310, 10);
    outArea = new CTextArea(size, k3DOut);
    frame->addView(outArea);

    frame->setTransparency(false);
    frame->draw();

    frame->setDirty(true);
    return true;
}

void Editor::close ()
{
    if (frame) {
        delete frame;
        frame = 0;
    }
    inArea = 0;
}

// 値変更コールバック(ボタン押下時に呼ばれる)
void Editor::valueChanged (CDrawContext* context, CControl* control)
{
    char buf[CTEXT_AREA_SIZE];
    convert(inArea->getText(), buf);
    outArea->setText(buf);
}

// WebAPIアクセス関数
void Editor::convert(char* src, char* dst)
{
    char sendbuf[CTEXT_AREA_SIZE];

    char* header = "http://aikelab.net/mikugo/api.cgi?chouon=Y&bunsetsu=Y&encoding=SHIFT_JIS&sentence=";
    strcpy(sendbuf, header);

    char buf[CTEXT_AREA_SIZE];
    urlencode(src, buf);
    strcat(sendbuf, buf);

    HINTERNET hInet;
    HINTERNET hFile;
    DWORD dwSize;

    hInet=InternetOpen("Mikugo", INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0);
    hFile=InternetOpenUrl(hInet, sendbuf, NULL, 0, INTERNET_FLAG_RELOAD, 0);
    InternetReadFile(hFile, dst, CTEXT_AREA_SIZE, &dwSize);
    InternetCloseHandle(hFile);
    InternetCloseHandle(hInet);

    // XMLからデータ部のみ抽出
    char* pos1 = strstr(dst, "<result>"); 
    char* pos2 = strstr(dst, "</result>"); 
    if ((pos1 == NULL) || (pos2 == NULL)) {
        *dst = '\0';
        return;
    }
    char* p = pos1 + 8;
    char* q = dst;
    for (; p < pos2; p++, q++) {
        *q = *p;
    }
    *q = '\0';
}

// 文字列URLエンコード関数
void Editor::urlencode(char* src, char* dst)
{
    char* p = dst;
    unsigned char c;

    for(unsigned int i = 0 ; i < strlen(src) ; i++)
    {
        c = src[i];

        if( (c >= '0' && c <= '9')
        ||  (c >= 'A' && c <= 'Z')
        ||  (c >= 'a' && c <= 'z')
        ||  (c == '-')
        ||  (c == '.')
        ||  (c == '_') ) {
            sprintf(p, "%c", c);
            p++;
        } else if( c == ' ' ) {
            sprintf(p, "+");
            p++;
        } else {
            sprintf(p, "%%%02X", c);
            p += 3;
        }
    }
}

DLLとソースコードは以下にあります。エラー処理とかも不十分なので実用には向きませんが参考にどうぞ。
 mikugovst.zip (Windows VST2.4)
 
VSTと言いつつただのテキスト処理ですみません。きっと次はちゃんと音の出るプログラムを作ります。
こんな感じでVST/VSTiをいっぱい作っていつか僕はシンセ界の神になりたいと思います。嘘です。