ビデオ会議で重要なのは音声だった

ビデオ会議システムを構築したところ、スムーズなコミュニケーションに重要なのは、

  1. 音声の質
  2. 映像のフレームレート
  3. 映像の解像度

という順に重要だということがわかった。音声でまず問題になったのがエコーで、エコーキャンセラーをソフトウェア的に実現*1しようとするもどうもうまくいかず、ハードウェア側で対応しているもの(今回はYAMAHAのYVC-1000)に切り替えたところ劇的に改善した。

このYVC-1000は、エコーキャンセルも強力ながらその他のビデオ会議向け音質改善技術(マイク自動追尾、オートゲインコントロール、ノイズリダクション、残響抑圧、オートルームEQ)が搭載されており、その機能によりビデオ会議のクオリティが大変向上した。これらの機能は簡単に言うと人の声以外の音をカットし人の声のみを強調し、その音圧を一定にする。これにより非常に聞き取りやすくなる。YVC-1000のマイクの前で小さめの声で喋ってもそれを拾って聞きやすい音量で再生するため、遠隔地にいるほうがささやき声的な発言だと聞きやすいという逆転現象さえ起きてしまった。

ビデオ会議に不満がある方は導入検討の価値ありだと思う。

YVC-300

YVC-1000単体だと約10万円かかるが、ほぼ同機能が搭載されたスピーカー・マイク一体型のYVC-300が約4万円。
YVC-300 - スピーカーフォン/マイク&スピーカー - ヤマハ株式会社

その他スピーカーフォンメーカー

*1:オープンソースのものはwebrtcで実装されている

openFrameworksでWebカメラを自動的に接続する

oFで自動的に接続するシリーズ。

ofVideoGrabberで適当にデバイスの数字とかでやってるとノートPC内蔵のWebカメラ起動しちゃったりするんだけど、それを避けて常に特定のカメラを開けるようにする。避け方は簡単でWebカメラの名前(=ofVideoDeviceのdeviceName)を見て開けばOK。今回はロジクールのC920ってカメラだからC920って名前があるやつを開くだけ。

#define CAM_WIDTH 1296
#define CAM_HEIGHT 729

ofVideoGrabber cam;

void HogeClass::setup(){
    if(cam.isInitialized() == false){
        cout << "Initalizing cam" << endl;
        int index = 0;
        vector<ofVideoDevice> devices = cam.listDevices();
        for(int i=0; i<devices.size(); i++){
            ofVideoDevice& device = devices.at(i);
            cout << i  << ":" << device.deviceName << ":" << endl;
            if(device.deviceName.find("C920") != std::string::npos){
                index = i;
            }
        }
        cam.setDeviceID(index);
        cam.initGrabber(CAM_WIDTH, CAM_HEIGHT);
        cout << cam.getWidth() << "," << cam.getHeight() << endl;
        
        return;
    }
}

CAM_WIDTHとCAM_HEIGHTの数字はC920における秘伝のタレ。良いカメラでっせ。

Logicool ロジクール HD プロ ウェブカム c920r

Logicool ロジクール HD プロ ウェブカム c920r

2018/05/16 コード修正

@shigeodayo氏に指摘されてdevice.deviceName.find()のところの判定をちゃんとstd::string::nposにするように変更。また、cam.listDevices()がループ内で呼び出されてコンソールに意図しない出力が出てるのも修正。

openFrameworksからArduino Unoを自動的に接続する

openFrameworks v0.9.8

毎回昔のコードを掘り出すのがめんどくさくなってきたので、ここに書いておく。たぶんArduinoUnoに限らずFTDIのチップで動くUSBシリアル変換デバイスを開くと思う。

ofSerial serial;
bool serialStatus;

void HogeClass::setup(){
    serial.listDevices();
    vector <ofSerialDeviceInfo> deviceList = serial.getDeviceList();
    int numOfOpendDevice = 0;
    for (int i=0; i<deviceList.size(); i++) {
        ofSerialDeviceInfo& info = deviceList.at(i);
        string dn = info.getDeviceName();
        if (ofIsStringInString(dn, "cu.usbserial") || ofIsStringInString(dn, "cu.usbmodem")) {
            serialStatus = serial.setup(info.getDevicePath(), 9600);
            break;
        }
    }
}

【永久保証付き】Arduino Uno

【永久保証付き】Arduino Uno