DS-DT310をSDR#でいろいろ受信してみたんですが、そろそろ飽きてきたので、なにかコードを書いてみようかと思ったのですが、とりあえず、C#から使ってみようということです。
さすがにDSPのコードをC#で書こうということはしませんが、簡単な処理なら多少非力なCPUでも処理できるのではないかと思います。
[PR] 楽天でDS-DT310をチェック
librtlsdr.libを用意する
まずは、osmocomのwikiに"pre-built Windows version"というリンクがあるので、そこからlibrtlsdrが入ってるzipファイルをダウンロードします。そこにx64とx32のフォルダがあり、その中にあるDLLが必要です。
あと、rtl-sdr.hというファイルがありますが、このヘッダを参考にDllImportしますので、これも必要です。
VS2013のC#プロジェクトの設定
まず、普通にC#でプロジェクトを作成します。このプロジェクトにlibrtlsdrのDLLを追加するのですが、x64かx32のどちらか一方だけを追加します。
追加したDLLのターゲットにあわせて、プロジェクトの構成マネージャーを変更します。VSのツールバーに"x32"とか"Any CPU"を選ぶところがあるので、そこで変更できます。
あと、このまま、ビルド、デバッグするとDLL見つかりませんといわれてしますので、ビルド後にDLLを実行するフォルダにコピーするようにします。
プロジェクトのプロパティにビルドイベントいうのがあり、「ビルド後に実行するコマンドライン」という項目に以下のコマンドを入れればよいです。
copy "$(ProjectDir)*.dll" "$(TargetDir)"
DllImportの定義
C#からlibrtlsdrのDLLにある関数を呼び出すためにDLLImportをつかってC#のメソッドといて呼びさせるように定義します。
以下にDllImport定義の一部です。これを参考に必要な関数も定義してください。
[DllImport("rtlsdr.dll", CharSet = CharSet.Ansi)]
extern static int rtlsdr_get_device_count();
[DllImport("rtlsdr.dll", CharSet = CharSet.Ansi)]
extern static IntPtr rtlsdr_get_device_name(int index);
[DllImport("rtlsdr.dll", CharSet = CharSet.Ansi)]
extern static int rtlsdr_open(out IntPtr dev, int index);
[DllImport("rtlsdr.dll", CharSet = CharSet.Ansi)]
extern static int rtlsdr_close(IntPtr dev);
[DllImport("rtlsdr.dll", CharSet = CharSet.Ansi)]
extern static int rtlsdr_reset_buffer(IntPtr dev);
[DllImport("rtlsdr.dll", CharSet = CharSet.Ansi)]
extern static int rtlsdr_read_sync(IntPtr dev, IntPtr buf, int len, out int n_read);
[DllImport("rtlsdr.dll", CharSet = CharSet.Ansi)]
extern static uint rtlsdr_get_center_freq(IntPtr dev);
[DllImport("rtlsdr.dll", CharSet = CharSet.Ansi)]
extern static int rtlsdr_set_center_freq(IntPtr dev, uint freq);
【追記】.Net4以降では、DllImportの中に"CallingConvention=CallingConvention.Cdecl"を追加してください。
librtlsdrの関数の使い方
rtlsdr_get_device_name()は、IntPtrを返しますが、これをSystem.Runtime.InteropServices.Marshal.PtrToStringAnsi()を使って、文字列に変更します(ただし、本当にANSIなのかはわかりませんw、とりあえずです)。
サンプルの読み込みは、非同期ではなく同期関数rtlsdr_read_sync()を使います。当然ですが、この関数はブロックするので、スレッドの内でループして読み込みようにします。また、rtlsdr_read_sync()に渡すバッファは、System.Runtime.InteropServices.Marshal.AllocCoTaskMem()を使って確保したほうがいいと思います。ちなみに送られてくるデータはosmocomのwikiに書いてあるとおり"8-bit I/Q-samples"です。
あと、 rtlsdr_open()を呼び出した後、rtlsdr_read_sync()を呼び出す前に、rtlsdr_reset_buffer()を呼んでおく必要があるようです。
おわりに
これでとりあえずは、librtlsdrの関数を呼び出すことができるようになったわけですが、あとはrtl-sdr.hのコメントやlibrtlsdrのソースコード(いくつかのコマンドのソースが含まれている)を見ながらコーディングしようと思ってます(まだ、細かいところまでは使ってない)。ちなみにlibrtlsdrのソースコードは、GitHubの中にあります。そこの右側にDownloadZIPというのがあるので、Gitがなくても入手できます。
0 件のコメント:
コメントを投稿