実験 6 通信基礎実験 2 1 目的 ネットワークを通じてデータ転送を行うことを体験的に学ぶために 本実験ではT CP/IPプロトコルを使い ワークステーション間で通信を行うクライアントサーバモデルのプログラムを作成する 今回は文字データだけでなく 音声データも使う事により より実践的なプログラミングを行う 2 解説 前実験と同様なので省略する 3 実験 実験 1で作成したプログラムを利用して マイクから入力した音声信号をサーバへ送信するクライアントプログラムを作成せよ 作成したクライアントプログラムから送信された音声信号が サーバプログラムで正しく再生されること -1-
4 実験結果 // 用意されたヘッダファイル #include < stdio.h> #include < fcntl.h> #include < netdb.h> #include < sys/types.h> #include < sys/socket.h> #include < sys/stat.h> #include < sys/signal.h> #include < multimedia/libaudio.h> #include < multimedia/audio_device.h> #include < netinet/in.h> #include < netdb.h > // 通信基礎実験 1より #define SERV_UDP_PORT 7777 // ポート番号の設定 #define MAXLINE 1024 #define Error ( void) fprf #define Verb if ( VFlag) fprf // 用意されたヘッダファイル // 音声信号を標準出力するプログラムより unsigned char buf[ MAXLINE ]; char *Audio_dev = "/dev/audio"; Audio_fd; // オーディオデバイス用ファイル記述子 IntFlag = FALSE; // SIGINT 用フラグ VFlag = FALSE; // char *program; initialize() { struct stat st; if ( stat( Audio_dev, &st) < 0) { Error( stderr, "%s: cannot open audio device n", program ); exit( 1 ); if (!S_ISCHR( st.st_mode)) { Error( stderr, "%s: %s is not an audio device n", program, Audio_dev ); -2-
exit( 1 ); // オーディオデバイスを open する if (( Audio_fd = open( Audio_dev, O_RDONLY O_NDELAY)) < 0) { Error( stderr, "%s: audio device open error n", program ); exit( 1 ); rec_sig() { // IntFlag をセットする Verb( stderr, "%s: send SIGINT n", program ); if (!IntFlag && ( Audio_fd > = 0)) { IntFlag = TRUE; if ( audio_pause_record( Audio_fd ) == AUDIO_SUCCESS) return; Error( stderr, "%s: could not flush input buffer n", program ); // ˆC を 2 回押したので, 無条件に終了する Verb( stderr, "%s: end by double sig n", program ); exit( 1 ); main( argc, argv) argc; char *argv[]; { cnt; ofd; c; // 通信基礎実験 1より n, sockfd, servlen, dummylen; sockb; // socket() ホフ皃 ヘ bindb; // bind() ホフ皃 ヘ struct sockaddr_in serv_addr, cli_addr; struct hostent *host; char *hname; char *program; char sendline[ MAXLINE ], recvline[ MAXLINE + 1 ]; -3-
// 通信基礎実験 1より extern char *optarg; extern optind; program = argv[ 0 ]; る host = gethostbyname( argv[ 1 ]); // 引数で指定したサーバ情報を host に代入す initialize (); // audio d e v i c e の初期化 signal( SIGINT, rec_sig ); // servaddrにサーバアドレスを設定する bzero(( char *) &serv_addr, sizeof( serv_addr )); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr( inet_ntoa( host-> h_addr )); serv_addr.sin_port = htons( SERV_UDP_PORT ); sockb = socket( AF_INET,SOCK_DGRAM,0 );/* キ 荀 socket () */ if( sockb==-1){ Error; exit( 0 ); // cliaddrにローカルアドレスを設定する bzero(( char *) &cli_addr, sizeof( cli_addr )); cli_addr.sin_family = AF_INET; cli_addr.sin_addr.s_addr = htonl( INADDR_ANY ); cli_addr.sin_port = htons( 0 ); bindb = bind( sockb, ( struct sockaddr *)&cli_addr,sizeof( cli_addr )); if( bindb==-1){ Error; exit( 0 ); /* main loop */ -4-
// while ( 1) { 通信基礎実験 1より // バッファにデータを読み込む cnt = read( Audio_fd, ( char *) buf, sizeof ( buf )); if ( cnt == 0) break; if ( cnt < 0 ) { // エラーもしくは入力待ちの場合 if ( IntFlag) break; // ˆC が押されていたら終了する continue; // ˆC が押されていないとき if( sendto( sockb,buf,strlen( ( char *) buf ),0,( struct sockaddr *) &serv_addr,sizeof( serv_addr )) ==-1) // 音声信号を送る Error; // 通信基礎実験 1より close( sockfd ); exit( 0 ); // 後処理 ( void) close( ofd ); ( void) close( Audio_fd ); Verb( stderr, "%s: end of program n", program ); 音声信号を標準出力するプログラムより 以上のプログラムを使用 マイクに音声を入力すると サーバ側で再生される事を確認 -5-
5 考察 1 本実験では音声データの通信を行ったが 計算機で音声データを扱いプログラムを作成する場合 通信を行うプログラムを作成する場合 それぞれ注意すべき点を検討せよ 音声データがリアルタイムで送られてくる場合 文字データと比べものにならないほどのリソースを要する そのため 余分な処理を最小限に抑え 高速で処理出来るように配慮すべきだと思われる 2 通信プログラムの応用として どのようなアプリケーションが考えられるか 作ってみたいか検討せよ その実現に必要となる技術が有ればそれもあわせて検討せよ 1 音声の保存と入出力 音声で保存するメモ帳プログラム ボイスチャット 2 音声を文字として認識させる 入力された言葉を文字として取り入れるプログラム 入力された文字を翻訳し 音読させるプログラム( 翻訳機 ) 3 音声を音程として認識させる 入力された音を音階で保存するプログラム 入力された音楽の楽譜を作るプログラム 4 音声に何らかの変化を加える オーケストラなどの音楽から 周波数帯域を一部分だけ抜き出し 楽器ごとに音を分けて保存するプログラム 可聴周波数以上の音声の中間周波数を取り 可聴周波数まで下げる事により 擬似的に超音波を聴くプログラム 1について保存に関しては サウンドレコーダ ボイスチャットに関しては MSN メッセンジャー などで すでに実現されている ボイスチャットでは UDP では不便なので TCP を使っていると思われる 2にていて ドラゴンスピーチ ボイス一太郎 などで 実現されている しかし 精度はそれほど高くなく 実用的かどうかは微妙である 翻訳に対しても同じ事が言える 3について 鼻歌ミュージシャン などで実現されている 単音なら精度はかな -6-
り高い しかし雑音が入ってしまったり 和音が入ってしまうと認識されないのが現状 4について和音などの音階を取る事はとても難しいとされている 今 存在しているソフトウェアでは不可能だろう 自分が開発するとしたら 周波数帯域を区切るのではなく 波の形から一部の楽器を取り出す方法を提案してみたい バイオリンの響きとトランペットの響きを比べると バイオリンの方が振動が格段に多いはずである 可聴周波数云々は何故考えついたかというと 動物の声には超音波がつきものらしい 有名なのがイルカとコウモリ 彼らの声を人間の耳で確認するのは難しい ( 可聴周波数も使うので聞こえる声もある ) それを 擬似的にでも聞けたら面白いと思った 3 ネットワークセキュリティに関する問題点や利用技術について 自分でテーマを設定し考察せよ セキュリティ向上のためのプロトコルは多数存在する SSH SSL などには関わりもある どちらも暗号化と認証を謳っている 最近では Yahoo! JAPAN のメールサービスなどにも SSL が使われるようになったが 知っている人間はごく少数だろう 量子コンピュータが完成したら一般的な暗号化は無意味になるという話を聞くが そんな問題よりも 知らずに telnet を使い続けている人に目を向けた方が良いのではないだろうか どんな高度な技術もプログラムも エンドユーザが使用出来なければたいした意味は持たない Windows XP が出た当初はエンドユーザーコンピューティングという言葉をたびたび耳にした気がするが 最近は聞いた覚えがない 4 本実験を行って 難しかった点 興味を持った点 その他について感想を述べよ プログラム自体は切って張ってを繰り返しただけなので 大して難しい作業でもなく 大した問題もなく出来た 内容を理解したかどうかはいつも道理微妙である 一度感覚を理解してしまえば テンプレートなり アプリケーションなりで行うので 問題は無くなるのだろうが 最初の理解が難しい -7-