EmpathをVisual Studio(C++)で使ってみた

# Empathとは
[Empath](https://www.webempath.com/)は音声認識AIや感情分析AI、会話分析AIを開発しています。
Empathに登録するだけで、誰でも無料でEmpath WebAPIを用いて音声感情分析をすることができます。

# 前提
http通信とか全くわからないけどとにかくC++でEmpathAPIを使ってみたかった

# 環境
Windows11(curl標準搭載)
Visual Studio 2022


# 1. 【準備その1】libcurlのインストール
こちらのサイトの通りにやります。
[【cURL】libcurlをVisual Studio 2019で使う方法](https://chiegra.com/curl-vs2019/)

まず、[curlのサイト](https://curl.se/)のDownload→Browse Sourceをクリックし、curlのソースコードをダウンロード

~~~ruby:Command Prompt
置きたい場所>git clone https://github.com/curl/curl.git
~~~

次に、自分の使っているVisual Studioの開発者ツールを起動し、先ほどcloneしたフォルダの直下にあるbuildconf.batを起動した後、nmakeでコンパイルします。私は64bit OSを使っているので、"x64 Native Tools Command Prompt for targeting x64”を使いました。コマンドは以下です。

~~~ruby:x64 Native Tools Command Prompt for targeting x64
置いた場所>cd curl
置いた場所/curl>buildconf.bat
置いた場所/curl>cd winbuild
置いた場所/curl/winbuild>nmake /f Makefile.vc mode=dll MACHINE=x64
~~~

実行した結果、置いた場所/curl/builds以下に、
* libcurl-vc-x64-release-dll-ipv6-sspi-schannel
* libcurl-vc-x64-release-dll-ipv6-sspi-schannel-obj-curl
* libcurl-vc-x64-release-dll-ipv6-sspi-schannel-obj-lib

の3つのフォルダが作成されます。
置いた場所/curl/builds/libcurl-vc-x64-release-dll-ipv6-sspi-schannel/binを環境変数Pathに追加します。

# 2. 【準備その2】Empathの準備
[Empathのサイト](https://webempath.net/lp-jpn/)の一番下に、以下の画像のようなページがあるので、「お申込みはコチラ」をクリックし、会員登録します。
![スクリーンショット_20230106_030729.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540665/94deb76d-5a8d-fa15-bef3-cf9eb1d05565.png)

登録したら、[ログインページ](https://webempath.net/sign_in)からログインし、「APIKey設定」を開きます。
右下の黄緑色の「追加」ボタンを押して、適当に名前を付けるとAPI Keyが発行されます。
「ドキュメント」ページにはEmpath WebAPI仕様書が置いてあるのでダウンロードしましょう。

# 3. Empath APIを使ってみよう！
まず、以下の規定に従った音声ファイルを用意します。
* PCM WAVE形式、16bit
* データサイズ1.9MB以下
* フォーマットがPCM_FLOAT、PCM_SIGNED、PCM_UNSIGNEDのいずれか
* 録音時間5.0秒未満
* サンプリング周波数11025Hz
* チャンネル数1(モノラル)

次に、Visual Studioでソリューションファイルを作成します。
(「新しいプロジェクトの作成」→「コンソールアプリ」)
ソースファイルには、以下を記述します。
~~~ruby:main.cpp
#include <curl/curl.h>

int main(int argc, char *argv[])
{
  CURLcode ret;
  CURL *hnd;
  curl_mime *mime1;
  curl_mimepart *part1;

  mime1 = NULL;

  hnd = curl_easy_init();
  curl_easy_setopt(hnd, CURLOPT_BUFFERSIZE, 102400L);
  curl_easy_setopt(hnd, CURLOPT_URL, "https://api.webempath.net/v2/analyzeWav");
  curl_easy_setopt(hnd, CURLOPT_NOPROGRESS, 1L);
  mime1 = curl_mime_init(hnd);
  part1 = curl_mime_addpart(mime1);
  curl_mime_data(part1, "(自分のAPIKey)", CURL_ZERO_TERMINATED);
  curl_mime_name(part1, "apikey");
  part1 = curl_mime_addpart(mime1);
  curl_mime_filedata(part1, "(.wavファイルのパス)");
  curl_mime_name(part1, "wav");
  curl_easy_setopt(hnd, CURLOPT_MIMEPOST, mime1);
  curl_easy_setopt(hnd, CURLOPT_USERAGENT, "curl/(curlのバージョン番号)");
  curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
  curl_easy_setopt(hnd, CURLOPT_CUSTOMREQUEST, "POST");
  curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
  curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);

  /* Here is a list of options the curl code used that cannot get generated
     as source easily. You may choose to either not use them or implement
     them yourself.

  CURLOPT_WRITEDATA set to a objectpointer
  CURLOPT_WRITEFUNCTION set to a functionpointer
  CURLOPT_READDATA set to a objectpointer
  CURLOPT_READFUNCTION set to a functionpointer
  CURLOPT_SEEKDATA set to a objectpointer
  CURLOPT_SEEKFUNCTION set to a functionpointer
  CURLOPT_ERRORBUFFER set to a objectpointer
  CURLOPT_STDERR set to a objectpointer
  CURLOPT_HEADERFUNCTION set to a functionpointer
  CURLOPT_HEADERDATA set to a objectpointer

  */

  ret = curl_easy_perform(hnd);

  curl_easy_cleanup(hnd);
  hnd = NULL;
  curl_mime_free(mime1);
  mime1 = NULL;

  return (int)ret;
}

~~~

実はcurlは便利で、curlのコマンドの最後に --libcurl (生成したいC++ファイルの名前)を付ければ勝手にlibcurl用のソースコードを作ってくれます！
なので、上のコードをわざわざコピーする必要はなく、

~~~ruby:Command Prompt
curl -X POST -F apikey=YOUR APIKEY -F wav=@/PATH/TO/WAVFILE.wav https://api.webempath.net/v2/analyzeWav --libcurl FILENAME.cpp
~~~

でできたファイルをソースファイルにすればよいです。超簡単。

Releaseになっていることを確認して、依存関係の設定をします。
* 「プロパティ」→「C/C++」→「全般」→「追加のインクルードディレクトリ」に、置いた場所/curl/builds/libcurl-vc-x64-release-dll-ipv6-sspi-schannel/includeを追加
* 「プロパティ」→「リンカー」→「全般」→「追加のライブラリディレクトリ」に、置いた場所/curl/builds/libcurl-vc-x64-release-dll-ipv6-sspi-schannel/libを追加
* 「プロパティ」→「リンカー」→「入力」→「追加の依存ファイル」に、置いた場所/curl/builds/libcurl-vc-x64-release-dll-ipv6-sspi-schannel/lib/libcurl.libを追加

以上の設定が終わったら、ソリューションをビルドして実行します。結果は以下のようにjson形式で返ってきます。
~~~
{"error":0,"calm":35,"anger":0,"joy":0,"sorrow":14,"energy":0}
~~~
errorの値が0ならば成功、それ以外ならエラーが出ています。
今回のようにAPI v2を利用している場合は、エラーが出た場合は応答に"msg":(エラーメッセージ)が含まれます。

# 感想
こんなに簡単に音声感情分析が利用できるとはびっくり！
ただ、5秒以内なのと、wavファイルでなければいけないという点で利用ハードルがちょっと高いなあと思いました。
もし何か間違ったことを書いていたらぜひ教えてください。