2017年6月22日木曜日

libasound によりPCM音声録音

libasound によるPCM音声録音の例題です。

Linux や Raspberry にてコマンドラインからマイクに接続し音声を WAVE ファイルとして保存します。
libasound がインストールされていない場合、下記のコマンドによりインストールしてください。 また、例題のような自分で録音用のコーディングをしなくてもツール群が提供されています。 alsa-utils に含まれる arecord コマンドにて録音、aplay コマンドにより再生が可能です。
この arecord コマンドにより、PC にマイク機器が接続されているかを確認することができます。 表示される「カード 1」が例題にて使用するマイク番号で、使用するマイクの記述方法は「hw:1」や「plughw:1」と言う形式になります。
「hw:1」を利用するとマイクからの入力がそのまま録音されるので 44100Hz 等のサンプリングレートを変えることはできませんが、「plughw:1」を利用するとソース上からダウンミックスした形でサンプリングレートを変更することができます(標準は 8000Hz で 他のサンプリングレートも指定できます)。

例題では、使用するマイクの番号、サンプリングレート、保存する秒数を指定して録音を開始し、ファイル名「record_マイク番号.wav」にて保存しています。
実行結果

2017年6月21日水曜日

WAVE/PCM 音声の生成

WAVE/PCM 音声を生成する例題です。

WAVE 音声に関して以前まとめたものはこちら(WAVEファイルの読込み/再生

WAVE 音声のフォーマットに合わせてヘッダを書き込み(2ch, 44100Hz)、sin 波形の振幅を徐々に大きくした音声を生成しています。 実行結果(Audacity にて表示)

ローカルネットワークから NetBios 名の取得

ローカルネットワークから Windows および Samba でのファイル共有を行っているマシンの NetBios 名を取得する例題です。

例題では、自機のIPアドレスからスキャンを行うIPアドレスの範囲を設定し、それぞれのアドレスに対して NetBios 名を取得しています。
NetBios 名を解決するための手順を省略している部分もあるため上手く取得できない場合もありますが、Windows マシンでは概ね正常に動作しています(Samba のネームサーバー/nbmd に対して取得できない場合も)。 実行結果

2017年6月20日火曜日

CGI に対応した HTTP リクエストによるファイル保存

CGI に対応した HTTP リクエストによるファイル保存の例題です。

ソケット通信を用いて HTTP リクエストを行う場合、レスポンスヘッダに含まれる Content-Length が 0 となり正しく本文が取得できない場合があります(libcurl 等を用いるとその辺の処理は自動的に行ってくれます)。
Apache サーバーに index.html 等のファイルを直接要求した場合にはそのようなことはありませんが、リクエストしたページが CGI で構成されている場合にそういう状況が発生します。
CGI はファイルの読み出しやページの生成の都合に応じて、逐次転送を行いますので、Content-Length の代わりにこれから送信するバイト数を16進数字にて送信しその本文を送信した後、転送が終われば 0 の文字列を送信します。

CGIによるファイル送信の流れ
レスポンスヘッダ
9bd9
[9bd9バイト分のデータ]
e000
[e000バイト分のデータ]
0
例題では、HTTP リクエストを送信後 Content-Length が含まれるかどうかで CGI かどうかを判定し、受信処理により取得された本文をファイルとして保存しています。 実行結果

libjpeg によるカラーバーの作成

libjpeg により JPEG 画像でのカラーバーを作成する例題です。

apt-get や brew(OSX)等により libjpeg をインストール後、libjpeg へのリンク(-ljpeg)を追加しビルドしてください。

例題では、128x32 のサイズの RGB画像が作成され、JPEGファイルとして保存されます。
HDDの使用率等を示すようなカラーバーが作成されます(例題では50%の使用率)。 実行結果(カラーバー:50%の使用率)

NTPサーバーからの時刻取得

NTPサーバーから時刻を取得し表示する例題です。

NTPサーバー(time.asia.apple.com)は適宜変更してください。
実行結果

レーベンシュタイン距離により名前の類似度順に並べ替え

レーベンシュタイン距離により名前の類似度順に並べ替え表示する例題です。

例題では、「佐藤浩市」と言う名前に対する類似度をレーベンシュタイン距離により計算し、その距離に応じて qsort により近い順に並べ替えて表示しています。
実行結果

UNIX名前付きパイプによるスレッド間通信

FIFO(名前付きパイプ)によりスレッドやプロセス間の通信を行う例題です。

FIFO は UNIX 上ではファイルとして作成することができますので、スレッドやプロセス間等様々な状況において簡単に通信を行うことができます。
例題ではソースを分割して用意すると分かりにくくなりますので、main 関数から読み込み用のスレッドに対して文字列を送信すると言う形になっています。
実行結果

2017年6月17日土曜日

重複なしの乱数発生(初期値の指定)/Javascript・Perl版

重複なしの乱数発生 を修正し、100〜200までの値を発生する等、初期値を指定した乱数を発生させる例題です(初期値100、個数100での乱数発生)。

エクセルや既存のサイトのCGI等でそのようなことは可能かもしれませんが、5000個、10000個ともなってくるとスクリプトや従来の重複なしの方法では相当に時間がかかってしまうので、コマンドラインツールとして利用することが主な目的になります。

また、Javascript・Perl版も用意しています。
10000個の乱数発生では、Cで作成した場合には0.1秒、Perlで作成した場合には5秒近くと速度は圧倒的に違いますが、CGI等で利用するための参考として。

randtable.cpp 実行結果 Javascript randtable.pl / Perl

2017年6月2日金曜日

strtok_r によるネスト化されたトークンの切り出し

strtok_r によるネスト化されたトークンの切り出しの例題です。 テキストファイルを読み込み、単語ごとにハッシュ表を作成し、出現する頻度を表示する例題も兼ねています。

strtok 関数はスレッドセーフ化されておらず、再入可能(リエントラント)な利用には向いていません。
strtok 自体が最初の引数で与えられた文字列を変更してしまうためや、内部で確保された文字列の中身を変更してトークンとして切り出しているためです。
while 内に while 文で strtok を呼び出したり、別のスレッドで strtok を呼び出した場合、最後に呼び出された strtok により内部の文字列が変更され、思い通りの結果が得られないと言う状況が発生します。
また、ある関数で strtok を使っていて、その結果から別の関数を呼び出した場合、ソース上からは見えない状況で正しい結果が得られないと言うことにもなり得ます。
strtok_r はこのような状況においても現在扱っている文字列の処理に影響が及ぶことはありません。

以下のソースでは、テキストファイルの内容を全てメモリ内に格納した後、strtok_r にて改行(\n)とスペース( )により単語を抜き出し、ハッシュテーブルへの登録や頻度のカウントを行っています。
loadHashBAD 関数は strtok により処理を行うもので、思い通りの結果が得られていないことが分かります(一行目の単語しか抽出できない)。
loadHash 関数にて strtok_r を利用することにより全ての行の単語が抽出されます。 実行結果(strtok を使用した場合:loadHashBAD) 実行結果(strtok_r を使用した場合:loadHash) file.txt の内容