mikulogic-tomo’s diary

NagaokaMikunologicalLive主催者のブログです。色んなこと書きます。

Android開発日記 AndroidのBluetooth通信(SPP)【初心者向け】

今回はスマホAndroid)とPC間で、Bluetooth通信をやってみました。

Androidを使ったBluetooth通信の記事を調べると以下のサイトが出てくると思います。
https://www.bright-sys.co.jp/blog/android-using-bluetooth-spp/www.bright-sys.co.jp

これはGoogleが提供しているサンプルコード「BluetoothChat」を解説しているサイトなのですが、初心者からするととても分かりづらいです。
まずは、ボタンを押したら「HelloWorld!」って表示されるところから始めたいですよね・・

分かりやすい記事を調べるのですが、見つけることが出来ず苦労したので、これからAndroidBluetooth通信を始めたいって方に役立つような内容にしました。
このBluetoothChatの中にある機能から必要最低限のメソッドだけを取り出したコードです。
(コードの全ては最後に記載してあります。)


まず、AndroidにはBluetooth用のクラスが既に用意されていますので、ソケット通信に必要な知識(Listenやbind、acceptなど)は恐らく必要ないです。
(知っているに越したことはないですが)

基本的にコード上で用意する順番として、
BluetoothAdapter

BluetoothDevice

BluetoothSocket

OutPutStream

ソケット通信を行う
といった流れです。

また、Bluetooth同士は既にペアリングしてあることが前提として行います。
(ペアリングに関しては他のサイトで調べてください。)


具体的に説明していきます。
まず、Bluetooth同士が通信を行うためには相手のデバイス物理アドレスが必要になります。
サーバー側となるPC側は設定する必要はありませんが、(PC側の説明は後半にあります)スマホ側は相手(PC側のBluetoothアダプタの物理アドレス、以降、MacAddress)を指定してあげる必要があります。

MacAddressを調べるには以下の方法で行います。
f:id:mikulogi-tomo:20180104014508p:plain
バイスマネージャーを開いてBluetoothのプロパティを開きます。
f:id:mikulogi-tomo:20180104014854p:plain
図上で黒くなっている部分に書いてある数字がMacAddressです。(後で使用します)
このようにして確認できます。

これで準備は完了です。
コードを見ていきます。

    private BluetoothAdapter mBTAdapter = null;//Bluetooth通信を行うために必要な情報を格納する
    private BluetoothDevice mBTDevice = null;//実際に通信を行うデバイスの情報を格納する
    private BluetoothSocket mBTSocket = null;//ソケット情報を格納する
    private OutputStream mOutputStream = null;//出力ストリーム

    private Button btnSend;//送信用ボタン
    private Button btnFinish;//終了用ボタン
    private TextView textview;//MacAddress表示用
    private String MacAddress = "○○:○○:○○:○○:○○:○○";//アルファベットは全て大文字出ないとエラーになる
    private String MY_UUID = "00001101-0000-1000-8000-00805F9B34FB";//通信規格がSPPであることを示す数字

MainActivityクラス内のメンバーです。
MacAddressは先程調べたものをアルファベットは大文字で書いて下さい。

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnSend = (Button)findViewById(R.id.btnSend);
        btnFinish = (Button)findViewById(R.id.btnFinish);
        textview = (TextView)findViewById(R.id.textView);
        btnSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(mBTSocket != null) {
                    Send();
                }
            }
        });
        btnFinish.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        //ソケットを確立する関数
        BTConnect();

        //ソケットが取得出来たら、出力用ストリームを作成する
        if(mBTSocket != null){
            try{
                mOutputStream = mBTSocket.getOutputStream();
            }catch(IOException e){/*ignore*/}
        }else{
            btnSend.setText("mBTSocket == null !!");
        }
    }

onCreate関数内では、
btnSendボタンが押されたらSend関数を
btnFinishボタンが押されたらfinish関数を呼ぶ設定をしています。
(Send関数はオリジナル、finish関数はアプリを終了させる時に呼ぶ関数)
その後、ソケットを確立する関数BTConnect関数(オリジナル)を呼び、
ソケットが取得出来たら(確立したら)、「mBTSocket.getOutputStream();」によって、出力用ストリームを作成しています。
(出力ストリーム関連はJavaの知識ですね)

先に、BTConnect関数から見ていきます。

    private void BTConnect(){
        //BTアダプタのインスタンスを取得
        mBTAdapter = BluetoothAdapter.getDefaultAdapter();

        textview.setText(MacAddress);
        //相手先BTデバイスのインスタンスを取得
        mBTDevice = mBTAdapter.getRemoteDevice(MacAddress);
        //ソケットの設定
        try {
            mBTSocket = mBTDevice.createRfcommSocketToServiceRecord(UUID.fromString(MY_UUID));
        } catch (IOException e) {
            mBTSocket = null;
        }

        if(mBTSocket != null) {
            //接続開始
            try {
                mBTSocket.connect();
            } catch (IOException connectException) {
                try {
                    mBTSocket.close();
                    mBTSocket = null;
                } catch (IOException closeException) {
                    return;
                }
            }
        }
    }

「mBTAdapter = BluetoothAdapter.getDefaultAdapter();」によって、
スマホが持っているBluetoothAdapterのインスタンスを取得できます。
次に、
取得したアダプタのインスタンスから
「mBTDevice = mBTAdapter.getRemoteDevice(MacAddress);」によって、
指定した物理アドレスを持つデバイス(相手デバイス)のインスタンスを取得できます。

相手のデバイスを指定出来たら、今度は通信を行うソケットを用意します。
どんな通信規格でやり取りするかを指定する必要があるので、UUIDを設定します。
(UUIDに関しては調べてください。私もよくは分かっていないので)

「mBTSocket = mBTDevice.createRfcommSocketToServiceRecord(UUID.fromString(MY_UUID));」
これによって、指定した相手デバイスとのSPPで通信するためのソケットが用意され、mBTSocketにそのソケット情報が格納されます。

最後に、
「mBTSocket.connect();」
によって、実際に接続され通信が確立します。
この時、相手側がスタンバイ状態(accept)でなければ、接続が失敗となります。

AndroidBluetooth通信でクライアント側の実装は、余計なものを省略するとこれだけで出来ます。
後は、Send関数内の処理は見た通りです。(Stream関連はjavaの知識(2回目))

    private void Send(){
        //文字列を送信する
        byte[] bytes = {};
        String str = "Hello World!";
        bytes = str.getBytes();
        try {
            //ここで送信
            mOutputStream.write(bytes);
        } catch (IOException e) {
            try{
                mBTSocket.close();
            }catch(IOException e1){/*ignore*/}
        }
    }

今回はサーバー側まで作ると大変でかつ、ややこしくなるのでサーバー側はTeraTermにお願いしています。

以降、PC側(TeraTerm側)の設定です。
SPP(Serial Port Profile) 通信ですので、シリアルポートを用意する必要があります。
まず、Bluetoothの設定画面を開きます。

COMポートタブを開き、追加を選択します。
「着信(デバイスが接続を開始する)」を選択し、OKを押します。
図のようにポート番号と着信が表示されていればOKです。
(最初、ポート番号が表示されていないかもしれませんが再起動とかすれば表示されると思います。)
f:id:mikulogi-tomo:20180104011633p:plain


TeraTermTeraTermに関しては解説しませんので、ググって下さい)を用意して、
新しい接続

シリアルのポート番号

先程表示されたポート番号を設定

準備完了です。

PC側の設定をざっくり言うと、
「シリアル通信用のポートを設定して、TeraTermでそのポートを指定して後は接続が来るまで待たせる」
となります。


TeraTermを待機させた状態で、スマホ側のアプリを起動してみます。
起動してすぐに、
f:id:mikulogi-tomo:20180104032738p:plain
この状態だと何らかの理由で接続が失敗しています。
f:id:mikulogi-tomo:20180104032749p:plain
この状態であれば、接続成功です!!
(黒い線のとこにMacAddressが表示されます)

真ん中の「HELLO WORLD!」をクリックするとTeraTerm上で「Hello World!」と表示されたと思います。
f:id:mikulogi-tomo:20180104024232p:plain
こんな感じで

以上で、Bluetoothを使った通信の基礎的な説明は終わりです。
実際に実用的なものになるためには、以下のような実装が必要です。

・デバイスの周りにあるBluetoothの検索
・接続するデバイスのペアリング設定
・既にペアリング済みのデバイスの一覧表示
・connect関数やwrite関数、read関数の非同期処理
AndroidはUI描画が行えるスレッドが一つしかないので、一定時間ブロッキング処理をUIスレッドで行うとシステムがインテントを投げます。)
・サーバー側の実装

何か気が遠くなりそうな作業量ですが、一つずつ実装していくしかないと思います。
サーバー側の実装はサーバーがスマホAndroid)かそれ以外かでまた変わると思います。
「BluetoothChat」で解説されているサーバーはスマホを使っています。
それ以外の場合だと、ガッツリ省略した通信に関する知識が必要になると思います。(Listenやbind、acceptなど)

ただ、今回の実装もそうでしたが、今はもう関数やクラスが用意されていることが多いです。(ゲーム用のDXライブラリとかも殆ど知識要らずに、IPを設定してあげるだけで、通信出来るようになりますもんね)
サーバー側の実装はUbuntu上のc言語で実装したことはありますが、windowsでは試してみましたがちょっと知識不足で出来なかったです(笑)
もし練習で行うのなら、Androidのサーバーを作るか、Linuxなど分かりやすいもので作ってみるといいと思います。
windowsでも直接c言語を叩いてDOS画面でコンパイルしてあげれば、動くのかな??今度、調べてみよう)


Bluetoothは色んなデータを通信できるので、SPP通信以外にも通信出来るようになりたいと思っています。
まあ、リモコンみたいな使い方なら今の知識で十分ではありますが、使える幅が狭いですからね、、、映像や音声をBluetoothでやりとりしてみたいです。


MainActivity.java

package com.example.○○○.bluetoothcom;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {

    private BluetoothAdapter mBTAdapter = null;
    private BluetoothDevice mBTDevice = null;
    private BluetoothSocket mBTSocket = null;
    private OutputStream mOutputStream = null;//出力ストリーム

    private Button btnSend;//送信用ボタン
    private Button btnFinish;//終了用ボタン
    private TextView textview;//MacAddress表示用
    private String MacAddress = "○○:○○:○○:○○:○○:○○";
    private String MY_UUID = "00001101-0000-1000-8000-00805F9B34FB";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnSend = (Button)findViewById(R.id.btnSend);
        btnFinish = (Button)findViewById(R.id.btnFinish);
        textview = (TextView)findViewById(R.id.textView);
        btnSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if(mBTSocket != null) {
                    Send();
                }
            }
        });
        btnFinish.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        //ソケットを確立する関数
        BTConnect();

        //ソケットが取得出来たら、出力用ストリームを作成する
        if(mBTSocket != null){
            try{
                mOutputStream = mBTSocket.getOutputStream();
            }catch(IOException e){/*ignore*/}
        }else{
            btnSend.setText("mBTSocket == null !!");
        }


    }

    private void BTConnect(){
        //BTアダプタのインスタンスを取得
        mBTAdapter = BluetoothAdapter.getDefaultAdapter();

        textview.setText(MacAddress);
        //相手先BTデバイスのインスタンスを取得
        mBTDevice = mBTAdapter.getRemoteDevice(MacAddress);
        //ソケットの設定
        try {
            mBTSocket = mBTDevice.createRfcommSocketToServiceRecord(UUID.fromString(MY_UUID));
        } catch (IOException e) {
            mBTSocket = null;
        }

        if(mBTSocket != null) {
            //接続開始
            mBTAdapter.cancelDiscovery();
            try {
                mBTSocket.connect();
            } catch (IOException connectException) {
                try {
                    mBTSocket.close();
                    mBTSocket = null;
                } catch (IOException closeException) {
                    return;
                }
            }
        }
    }

    private void Send(){
        //文字列を送信する
        byte[] bytes = {};
        String str = "Hello World!";
        bytes = str.getBytes();
        try {
            //ここで送信
            mOutputStream.write(bytes);
        } catch (IOException e) {
            try{
                mBTSocket.close();
            }catch(IOException e1){/*ignore*/}
        }
    }

    @Override
    protected void onDestroy(){
        super.onDestroy();
        if(mBTSocket != null){
            try {
                mBTSocket.connect();
            } catch (IOException connectException) {/*ignore*/}
            mBTSocket = null;
        }
    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.○○○.bluetoothcom.MainActivity">

    <Button
        android:id="@+id/btnFinish"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="終了" />

    <Button
        android:id="@+id/btnSend"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="100dp"
        android:text="Hello World!"/>

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="TextView"/>

</LinearLayout>

Android開発日記 ラジオボタンを使わずにラジオボタンを作る

こんにちは、ともです。

 

 今回は、ラジオボタンを使わずにButtonにラジオボタンの機能を持たせる方法です。

Android開発関連の初記事)

 

 普通はラジオボタンを使えばいいんですけど、実装してて後から普通のボタンからラジオボタンに変更したいってことがありました。その時は既にボタンを使って色々と実装していたので、このコードを変更するのは大変だな・・・と思ってこの形を取りました。

つまり、既にあるボタンにラジオボタンみたいな機能を持たせたって感じです。

ただ、後付けなのでコードの見た目がダサいです。嫌な方は最初からラジオボタンを使ってください。
また、調べてもそんな方法は見当たらなかったので、書いておきます。
(まあ、ラジオボタンを使えってことですね)



さて、ラジオボタンでは今選択しているものを表す印があると思います。
f:id:mikulogi-tomo:20180101142639p:plain
左図:RadioButtonを表示
右図:Buttonを表示

 
今回は左図のように、この丸いやつではなく、右図のようにボタンの背景を変更することによって選択されたことを表現します。

ボタンの背景を動的に変更させるためにはdrawableとViewクラス内のSelectedを使います。
app>res>drawableフォルダの中にselectorタグを持ったxmlを1つと、shapeタグを持ったxmlを2つ作ります。(AndroidStudio-Androidでのフォルダ階層)
xml」のファイル名は任意でOKです。
(今回の例では以下)
select_style.xml

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_selected="false"
        android:drawable="@drawable/default_style"/>
    <item
        android:state_selected="true"
        android:drawable="@drawable/pressed_style"/>
</selector>

default_style.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#3CB371" />
    <corners android:radius="8dp"/>
</shape>

pressed_style.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="#FFFF00" />
    <corners android:radius="8dp"/>
</shape>


メインとなるレイアウトのxml配置するボタンの背景(background)を以下のように設定します。
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    tools:context="com.example.○○○.buttonselect.MainActivity">

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/select_style"
        android:text="@string/button1"/>

    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:background="@drawable/select_style"
        android:text="@string/button2"/>

    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:background="@drawable/select_style"
        android:text="@string/button3"/>

    <Button
        android:id="@+id/button4"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:background="@drawable/select_style"
        android:text="@string/button4"/>

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="50dp"
        android:text="test"/>

</LinearLayout>

上記のようにxmlファイルを作成したら、後はメインのコード上で
「(Viewクラス).isSelected()」でselectフラグを確認でき、
「(Viewクラス).setSelected()」でselectフラグを変更できます。

しかし、ラジオボタンとは異なり、一つ選択されたら自動的に選択されていないボタンが変更されることはありません。
そのため、押されたボタン以外のselectフラグをfalseにしてあげる必要があります。
onClick関数は押されたボタンのみを通知するので、予め全てのボタンを配列にコピーしておいて、押されたボタン以外のselectフラグをfalseにしてあげます。

mainActivity.java

package com.example.○○○.buttonselect;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity{

    private Button btn1;
    private Button btn2;
    private Button btn3;
    private Button btn4;
    //コピー用の配列を用意
    private Button btn[] = new Button[4];
    private TextView textView;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //activity_mainレイアウトとMainActivityを関連付ける
        btn1 = (Button)findViewById(R.id.button1);
        btn2 = (Button)findViewById(R.id.button2);
        btn3 = (Button)findViewById(R.id.button3);
        btn4 = (Button)findViewById(R.id.button4);
        textView = (TextView)findViewById(R.id.text);

        //クリックリスナーを登録する
        btn1.setOnClickListener(btnOCL);
        btn2.setOnClickListener(btnOCL);
        btn3.setOnClickListener(btnOCL);
        btn4.setOnClickListener(btnOCL);

        /*
        * 既にあるボタンを配列の中にコピーする
        この部分でfor文などが使えないため、どうしてもコードがダサくなる
   */
        btn[0] = btn1;
        btn[1] = btn2;
        btn[2] = btn3;
        btn[3] = btn4;

    }


    View.OnClickListener btnOCL = new View.OnClickListener() {
        /*
        * 今回はリスナーを一つにして処理を行っているが
          下記onClick内の処理を他の関数にしてしまえば、
        * 現状のonClick関数に影響せずに実装することが出来る
  */
        @Override
        public void onClick(View v) {
            for(int i=0; i<btn.length; i++){
                if(v == btn[i]){//押されたボタンのみsetSelectedをtrueにする
                    btn[i].setSelected(true);
                    textView.setText("Button" + String.valueOf(i+1));
                }else{//押されていないボタンはsetSelectedをfalseにする
                    btn[i].setSelected(false);
                }
            }
        }
    };
}

注意する点として、
・初期状態ではselectが全てfalseになっていること
xmlにある「android:state_selected」以外の状態フラグ(例えば、android:state_pressedなど)が入ると意図しない動作になること
特に2つ目はハマりました・・・
これに関しては以下のブログにある内容の「4. selector 要素の子要素は、上から順に評価され、最初に一致したものが使われる」が参考になると思います。
listSelector のハマりどころ - Qiita



他にもっといい方法があるかもしれませんが、この方法のいいところはリスト状以外のラジオボタンを作れるところにあります。
ラジオボタンを使用すると、どうしてもリスト形式になります。(リスト状以外のラジオボタンもあるのかもしないですが)
好きに配置して、好きなデザインのボタンにラジオボタンの機能を持たせられるのはメリットなのかなと思っています。
ただ、ラジオボタンにある便利な機能(リスナーとか)は無いのでケースバイケースなのは間違いないですね


参考
【Android】selecterを使ってみる - It’s now or never
Android drawableは画像を入れておくだけじゃない - Qiita

ミクロジが生まれた経緯

こんにちは、ともです。

最近、よく見かける質問箱を作ったら、質問をして下さった方がいました。

(ありがとうございます!)

 

 

折角なので、ミクロジについて思うところを簡単に書こうかなと思います。

頂いた質問

どんなミクライブを作りたいですか?目指す方向性は?

 

この質問に対して私は「ライブの中心にいる初音ミクを表現したい」って答えました。

まあ、何とも当たり前なというか、初音ミクがいなければそもそもそのライブの意味ないしって思いますよねw

 

上手く表現できないんですけど、たぶんミク廃の方々なら分かってもらえると思います。

「ミクさんがいるからこんなに楽しい時間を過ごせて、面白いものを観れて、作れて、繋がりが出来ているんだ、初音ミクってやっぱり凄いな!!」

って

 

それこそ、こんな夢みたいなことばかりではありませんけど、やっぱり初音ミクが好きな理由はこれだと私は思います。

こんな思いをより強く実感した経験があります。

それは高田夜桜ミクライブです。

 

私は2016年に開催された高田夜桜ミクライブに初参加しました!
そこで受けた衝撃は今でも忘れられないです。

 

個人レベルでこんなに凄いものを創れるのか!しっかりしたものを創れば、人が集まり、それに皆が熱狂し、感動するものが出来るんだ!!

 

初音ミクという一つのキャラクターを中心に人が集まるその空間に何とも言えない感動を覚えました。勿論、その前に公式ライブ(マジミラ2015)にも参加済みではあり、そこでも同じような感動を抱きました。

ただ、高田夜桜ミクライブを見終わった後に、思ったことが

俺もこんなライブを創りたい

でした(笑)

 

公式が制作したライブは物凄くて感動するんですけど、個人で制作したものっていう点が大きかったと思います。

 

私が考えるミクロジの方向性はここから来ています。初音ミクを中心に人が集まり、感動して、楽しさを感じて、来てよかったと思えて貰えるようなものを創る。自分が感じた感動を初音ミクを知らない人にも感じてほしい、そんなことを考えています。

 

ミクさんが居なくても感動するものを創れれば凄いよね!そこに初音ミクが加われば、もっと感動するものになるよね!

よく分からない考え方かもしれませんが、兎に角、来てくれた人を感動させるものを創りたいと考えています。

 

最後に、、

ライブを創るに当たって一番の問題は、人員の確保です。私一人では絶対に創れないことは分かっていましたので、制作する仲間が必要でした。

ダメ元で、サークルの人に声を掛けてみたところ、運よくサークルの仲間が賛同してくれました。

ホントにこのときは有り難いことだなって強く思いました。

今でも賛同してくれる仲間には本当に感謝しています。ありがとう。

 

このような(私の中の)経緯で、ミクロジの種が生まれました。

そこからが大変で、いざ始めるって言っても何からすればいいのか分からないってところからでした。

その後の話はまた今度でノシ

 

追記

あっという間に、今年のミクロジ2017から3か月経ちました。時間の流れは早いものですね。

 

 

 

 

 

 

 

タブレットの映像をPCに表示しながら、PCの音とタブレットの音を同時に聴けるかどうかを試してみた

こんにちは、ともです。

何だかんだで書くことが出来たので書きます。(まだ、ミクロジのことではない…)

 

PCをしながらソシャゲをやってると、手の動きが

マウス→タブレット→マウス→タブレット→マウス→タブレット→・・・・

の繰り返しで一々手を動かすの面倒!!ってよく思うんです。

(マウスがトラックボールだから余計に…)

 

そこで探してみましたスマホの画面をキャプチャしてPC上で操作できるソフト

 

ありました↓

tonari-it.com

 

もし使いたい方が居たらここから調べてください。

 

実際に使うとこんな感じ

f:id:mikulogi-tomo:20171212004625j:plain

 

イラストリアスかわいい~(おっぱいでかい))

 

 

確かに希望した通り、マウスで操作は出来ました。

 

だが、遅延が酷い・・・

 

色々と設定を弄ってみたんですけど、どうもだめですね、

うん?これ、手を動かした方が早くないか?ってなりますw

 

設定が悪いのか、元々これくらいは妥協しないといけないのか・・そこら辺はよく分からないです。

(一つだけ、これ出来たら快適そうって思ったことがあったので、後述します。)

 

 

普通ならここで使うの止めると思うんですけど、ここで一つ思ったことが、

 

「PCに繋いでいるなら、PCの音をタブレットで再生できるんじゃないの??それなら、この機能使い続けてもいいかも?」

 

ってことです。

恐らく多くの方が「それ意味あるの?」って思ったと思いますw

PCの音をわざわざタブレットで再生するんですからねw

 

ただ私の場合、動画制作をしているにも関わらず、ノーパソのマザボに付いてる既存の端子から音を再生しています。

そのため、

「ステレオなのに完全に音がセパレートされてない・・・!!」

って現象や

「音がタブレットで聞いた方がいいんだけど…」

ってことに、ここ1年くらいで気づき、

(このパソコン自体は4年くらい使ってるから気づくの遅いw)

それからずっと音質が悩みでした。

 

いや、オーディオインタフェースを買えよってところなんですけど、

どれ買ったらいいの?てか、財政難だし・・・

って感じで、未だに買えてません・・・。

 

最近、買いたい意欲は凄く高まっているので、近いうちに買うとは思います。

Skypeとかしててもノイズが酷くて、うるさいしね)

 

また、逸れたので話を戻しますw

それで、

「オーディオインタフェースがないけど、タブレットで再生できれば綺麗な音で聴けるじゃん!!」

って思って、調べてみました。

 

ありました↓

www.gigafree.net

 

(これも使いたい人はry…)

 

使ってみたところ、

確かにPCの音がタブレットから聞こえてくる!

アズレンの音も同時に聞こえる!!

マウスでタブレットの操作もできる!!!

 

これはいい!

って思ったのもつかの間、

「あれ?音、ズレてない??いや、凄くズレてる…」

 

残念ながら、音ズレ発生してましたw

良質の音を聞くために、音ズレするなんて本末転倒ですよねw

 

結果、

PCにタブレットの画面を表示させて、マウスでタブレットを操作しながら、同時にPCの音も聞く

ってことは確かに出来ましたが、実用的ではないってところですね

 

音に関しては、オーディオインタフェースを購入することにします。

 

それで、後述するって言ってたことですが、

PC上に表示されるタブレットの映像が遅延するだけで、マウスの操作でリアルタイムにタブレットを動かせます。

そのため、タブレットを見ながら操作すると割と快適です。

ここで思ったのが

「この状態で、タブレットマウスポインタを表示出来れば、OKだよね??」

ってことです。

確かに、今回の目的ならタブレットの画面をPCに表示させる必要はないですからね

マウスをタブレットのある方向に持って行って、マウスポインタタブレットで表示出来れば、十分です。

 

こちらに関してはまだ調べていないので、もし何か分かったらここに書こうかなと思います。

何だかんだで、マウスから手を離さないのは、結構便利なので、暫くはこのソフトで操作してアズレンをします。

(↑結局、使う)

 

また、夜更かしをしてしまった・・。

 

 

 

ここまでの冒険を記録します

折角、始めたのでここまでミクロジ以外にどんなことをやっていたのか自己紹介がてら書きたいと思います。(さっきのに書けよ)

 

Twitter(@love_miku01)では初音ミクに限った話を出来るだけしてるので、私が他にどんなことをしているのか知らない方が多いと思います。

twitter.com

 

ミクロジに関してはまた今度、記述するとして大学に入ってから幾つかのサークルに所属していたんですが、今は下記のサークルに入ってます。

 

・天文(大学での正式名は理科学研究会)

・ソフトウェア開発(NUTソフトウェア)

 

天文部では学部2年から学部4年の春先まで、代表をしていました。

(学部2年での代表は大変だった、兎に角、サークルが無くならないように頑張りました)

元々、高校時代に地学部に所属していたことがきっかけで、大学でも天文部入りたいなって思って入りました。

天文部では1からプラネタリウムの制作を行いました。

以下が仲間と制作したドームです。

f:id:mikulogi-tomo:20171210215933j:plain

 

こんな感じに地球儀の表面みたいに丸くカーブした三角形を合わせて制作しています。

f:id:mikulogi-tomo:20171210220032j:plain

この黒いシートは軽いのに光を通さなくて安いという優れものの遮光シートです。

確か、これを使用しました。

www.tokoeizai.co.jp

もし、手軽に暗室とかを作りたいのであれば、断然オススメします!

 

(ただ、黒いのでプラネタリウムを作りたいのであれば、内側に白いシートを付けるという2度手間になります。プラネタリウムに関しては

星風Pさん(https://twitter.com/tagoshu)とか

ニコプラ部さん(

twitter.com

)にお伺いするといいと思います。)

話が少し逸れたので戻します。

 

実はこのドーム、この前に2回程失敗をして、3度目の正直って感じでやっと出来ました。今でも完成まで一緒に動いてくれた仲間に感謝してます。後輩もこのドームを使用してくれたみたいで、ホント嬉しいです。

 

天文部に関してはTwitterの垢と公式サイトあるんですけど、全然動いてないので、ここではリンク張りませんw

 

ミクロジ以外にも行ってたことがあって、ずっと言いたい欲があったので、すっきりしました(笑)

まあ、実際(ドーム制作は高校生でも出来ることなので)大したことはやっていないんですけどねw

いい思い出です。

 

 

それで、この3回目のドーム制作と同時並行で行われていたのが、「ミクロジ」です。

(語弊を生みそうだったので、追記しますけど、ドーム制作と同時並行だったのは2016年のときです。今年はドーム制作は関わっていないです。)

 

nutsoftware.webcrow.jp

 

ミクロジのために、天文部代表の私が何度かドーム制作中に抜けることがあって結構、仲間に迷惑を掛けました…。

 

ミクロジに関してはこちらで→(いつか書くw

 

他には、大学では情報系を学んでいるので、javaC++などを弄れます。最近はAndroid開発も行ったので、いつかそこら辺もまとめたいですね!

 

最後ですが、タイトルの「ここまでの冒険を記録します」は、ミクロジを運営しているNUTソフトウェアサークルのブログ名「ここまでの冒険を記録しますか」から来てます。

nut-softwaredevelopper.hatenablog.com

 

 

ライブ関連の情報ではなく、こちらはゲーム制作のノウハウを纏めています。

私は関わっていないですけど、宣伝です(笑)

 

これからの冒険に期待して、今日はここまでです。

 

(えっ、てか、ここまでの冒険、短っ…だいぶ大変だったことでも文字に起こすとこんなもんなんですねw)

 

 

 

 

 

初めまして

初めて、ブログを始めました。
絶対に続かないような気がするんだけど、まにまにで書いていきます。

 

今後書きたい内容としては、

・「ミクロジ」に関して

MMDに関して(あんまりないかも)

Android開発とか、javaとか、C++とか技術的なことに関して(一応、技術者になるらしいので←他人ごとみたい)

 

思い付くのはこんなところです。

よく書こうって思っても書いている途中でめんどくさくなったり、3日坊主になったりするので、どこまで続くのか分からないです・・・。

 

よろしくお願い致します。