信号生成アプリケーションを構築する方法の簡単なチュートリアル

信号生成アプリケーションを構築する方法の簡単なチュートリアル

わかりました、おかしいことはわかりますが、Wi-Fiカードで送受信する生データをサウンドデータとして聴きたいです。データがサウンドで送信されるのを聞くのは面白いだけです。私にとって唯一の実際の目的は、Wi-Fiカードがデータを転送するときにそれを知らせ、ネットワーク上で(やや)決定的なノイズ源を提供することです。非常に静かなオフィス。


オペレーティングシステム:Devuan Linux 5

カーネル: 5.10.0-17

WiFiカードドライバオープンソース:はい

ワイヤレスネットワークカード:ID 0bda:c820 Realtek Semiconductor Corp. 802.11ac NIC

答え1

最も簡単なアプローチは、このアプローチを変えることです。

sudo tcpdump -w - -U | aplay -

イーサネットインターフェイスからパケットをキャプチャしてプライマリオーディオデバイスに供給します。さまざまなフィルタtcpdumpや異なるサンプリングレートを試すこともできますaplay

時には面白いようです。個人的に私は沈黙が好きです。

答え2

私にとって唯一の実際の目的は、Wi-Fiカードがデータを転送するときにこれを知らせることです。

だからそれを使用してください。以下に、およびを使用する/sys/class/net/<interface name>/statistics/さまざまなカウンターがあります。一定の間隔でカウンタを読み取り、デルタを計算し、デルタを現在送信されているバイト量に応じて変調されているノイズなどの一種の音に変換する小さなプログラムを作成します。ノイズ音量やその他のパラメータを調整できます。rx_bytestx_bytes

答え3

私にとって唯一の実際の目的は、Wi-Fiカードがデータを転送するときにそれを知らせ、非常に静かなオフィスで(やや)決定的な騒音の原因を提供することです。

「生」のデータが聞こえない理由を説明する私の意見はとても過度でした。

しかし、あなたが本当に望むのは、テレフォンエンジニアが言うことです。快適な騒音いくつかの変化するデータを強化しました。

だから作ってみてください!このようなものを構築する方法の簡単な紹介は次のとおりです。ただフォローしてコピーして貼り付けたり、各ステップを詳しく見たりすることもできます。何でももっと面白いかもしれません:)

信号生成アプリケーションを構築する方法の簡単なチュートリアル

コンフォートノイズとGNUラジオコンパニオンの第一歩

コンフォートノイズセクションから始めましょう。 GNU Radioのインストールは簡単で実行も簡単ですapt install gnuradio。次に、GNU Radio Companionを開きます。

公式チュートリアルを読んでください。https://tutorials.gnuradio.org右側の検索ボックスを使用して両方のブロックを見つけます。

  1. オーディオレシーバー
  2. 騒音源

キャンバスに追加して接続します。 Noise Sourceブロックをダブルクリックし、出力タイプを「float」に変更します。

結果は次のようになります。

ノイズ源 - >オーディオレシーバー

同じ方法でsamp_rate変数ブロックを変更して、その値が48000になるようにします。 「移動」ボタンをクリックしてください。 (デスクトップ環境によって異なりますが、一般的には⏵の形で、実行メニューでも「実行」として見つけることができます。)

48000サンプリングレート

おめでとうございます。スピーカーでホワイトノイズが発生しています!ノイズ源の「振幅」を設定して音量を調整することもできます(1ではなく0.1で試してください)。

ノイズを形成し、フィルタリングを実行します。

素敵ですね。ローパスフィルタブロックを探し、ノイズ源とオーディオレシーバの間の直接的な接続を取り除き、その間にフィルタを配置してノイズをあまり迷惑にしないようにしましょう。フィルタを「Float -> Float(Decimating)」に設定し、カットオフ周波数を3000に、遷移幅を1500に設定します。これで、白いノイズをより人間に似たローパスノイズに変換しました。着色された騒音。試してみてください!

ノイズ源 - >ローパスフィルタ - >オーディオレシーバー

データレートをシステムに統合する方法

これで、システム全体に交通情報を追加する必要があります。

定期的にLinuxにネットワークインタフェースを通過したバイト数を尋ね、最後に要求された時点との差を計算することでこれを行うことができます。これにより、データレートを数値で取得できます。この数値が高い場合は、ノイズが大きくなるか、特定のトーンが高くなることを望みます。基本的に、私たちはこれを大きなモジュラーシンセに座っている完成した電子音楽アーティストと考えることができます。データレートによって異なります。

したがって、小さな問題があります。オーディオレシーバやノイズソースとは異なり、GNU Radioにはまだデータレートを計算するブロックは含まれていません。それは問題ではありません。私たちは自分で作ることができます。

しかし、どのように動作しますか?

少し後退してください。 「移動」ボタンをクリックするとどうなりますか?私の同僚GNU Radioの人々が近づいて見ました。フローチャートPythonプログラムをビルドして生成しました。

このプログラムは、追加するすべてのブロックをインスタンス化して設定し、GNU Radioランタイムに接続する方法を教えてくれます。その後、プログラムは実際にフローチャートを介してデータ転送を開始するように実行時に指示します。つまり、ノイズソースにノイズサンプルを作成するように指示し、そのサンプルが準備されたら、フィルタに次のようにフィルタリングするように指示します。 、オーディオシンクでフィルタリングされたサンプルがサウンドカードに提供されます。 (実際には同時にノイズ源がより多くのサンプルを生成し始め、すべてが並列に実行されます。)

したがって、ソフトウェアのすべての小さな部分は、接続された「アップストリーム」ブロックと対応する入力との間、およびその出力と「ダウンストリーム」ブロック間で交換される数値を生成、変換、または最終的に処理します。

進行中の開発作業

私たちが最終的に欲しいものは何ですか

したがって、私たちの使命は、同じことをする小さなソフトウェアを書くことです。フィルタの後に挿入するだけです。これが私が想像していた様子です:(これはモデルです!)

どのように見えるべきかについてのモデル

入力を出力にコピーし、ファイルから読み取ったいくつかの整数の変化率を乗算するブロック。

したがって、最初のパラメータは読み取るファイルの名前です。"/sys/class/net/wlp0s20u11/statistics/tx_bytes"ここではこれを使用します。 Wi-Fiカードのデバイス名に変更しますwlp0s20u11(疑わしい場合、ip linkまたはにお問い合わせくださいnmcli device)。

2番目のパラメーターは、継続的な更新のためにファイルを再読み込みする入力サンプルの数です。

それを構築

だからコーディングしました。あなたもできます! 「Embedded Python Block」ブロックを見つけてフローチャートに追加します。ダブルクリックしてプロパティを開き、[エディタで開く]をクリックしてから、このコードをコピーして貼り付けます(スペースが重要です!)。

import numpy as np
from gnuradio import gr


class blk(gr.sync_block):
    """
    Multiply by difference read from file

    This block reads an integer from a text file, after every configurable
    interval of input has been processed, calculates the per-sample rate at
    which that integer changed since the last read, and multiplies the input
    with that rate to calculate the output.

    Parameters:
     - filename                  The file to read periodically
     - read_every_n_samples      After how many samples to re-read to
                                 calculate the per-sample rate
     - max_increment_per_sample  The maximum rate to which we normalize
                                 our current rate. Set to 0 to not normalize.
    """
    def __init__(self,
                 filename="/sys/class/net/wlp0s20u11/statistics/tx_bytes",
                 read_every_n_samples=1000,
                 max_increment_per_sample=0):
        gr.sync_block.__init__(
            self,
            name='Multiply by difference from file',  # will show up in GRC
            in_sig=[np.float32],
            out_sig=[np.float32])
        self.interval = int(read_every_n_samples)
        self.next_read_in = self.interval
        self.filename = filename
        self.factor = 1
        self.max_increment_per_sample = max_increment_per_sample

    def read_value(self):
        with open(self.filename, "r", encoding="ascii") as file_handle:
            line_string = file_handle.readline()
            return int(line_string)

    def start(self):
        self.last_value = self.read_value()

    def work(self, input_items, output_items):
        in_stream = input_items[0]
        output = output_items[0]

        if self.next_read_in == 0:
            # We've reached the point at which we need
            # to update the factor with which we multiply!
            # So let's do that:
            new_value = self.read_value()
            difference = new_value - self.last_value
            rate = difference / self.interval
            if self.max_increment_per_sample > 0:
                rate = rate / self.max_increment_per_sample
                rate = min(1, max(rate, 0))
            self.factor = rate
            self.last_value = new_value
            self.next_read_in = self.interval

        # number of samples to which apply the same factor
        # This is at most as many items we currently have available at
        # the input, or as many items are left in this update period
        # (whatever is less)
        n_to_process = min(len(in_stream), self.next_read_in)

        # from current offset, the next n_to_process
        # input values get multiplied with the same factor
        # and written to the output
        output[:n_to_process] = in_stream[:n_to_process] * self.factor
        # We've consumed n_to_process input items, so we advance our
        # offset and reduce the amount of outstanding input
        self.next_read_in -= n_to_process

        # We consumed and produced n
        return n_to_process

エディタを保存して閉じます。

これで、プロパティダイアログボックスは次のようになります。

プロパティダイアログボックス

wlp…前述のように、Wi-Fiカードの実際のデバイス名に変更する必要があります。毎秒4回更新します(samp_rateサンプルを毎秒更新するので、これはsamp_rate / 4サンプルが一度更新されることを意味します)。毎秒最大速度を平均5・10⁶バイト/秒と見積もり、5・10⁶/samp_rateに設定しました。

結論として

カードに送信されたバイト数に基づいて、実際にノイズが発生するモデルを変換しました。文を書いただけでなく、試してみました!効果がある何もしない間はほとんど静かですが、まだ残っているチャットプログラムやチェックイン中の電子メールクライアントから一部のパケットが送信されることがありますが、アウトバウンドデータを送信するとパルスパケットが聞こえることを聞くことができます。

したがって、Pythonについて少し知っている(正直言ってあまり多くはありません)、上記のチュートリアルと私のソースコードを読みたい場合は、Python用のリアルタイム信号処理システムを構築したと正しく主張できます。音響ネットワークの状態を監視します。これは実際にはあまり悪くない偉業です。ここに尋ねる質問です。 :)

もちろんこれは完璧とは遠い。私が提供したPythonコードを修正したいかもしれません。スピードでログを取るのは良い考えかもしれません。したがって、(最後の比率を維持する代わりに)補間比率の点でよりスマートである可能性があります。 Pythonコードを書きたい場合は、ここが良い出発点になると思います。入力ノイズが必要な理由はありません。ノイズソースとフィルタの代わりに「Wavファイルソース」(WAVファイルだけでなく、Ogg vorbis、OPUS、MP4 AAC ...などのほとんどの圧縮オーディオフォーマットを読み取ることができます)を使用できます。お気に入りの音楽を作りましょう。

あるいは、GNU Radioと適切なアンテナを備えたコンパクトラジオ受信機(いわゆる「RTL-SDRドングル」)を使用して、実際にローカルラジオ局をキャプチャし、それをノイズではなく基本信号として使用することもできます。オプションは本当に多様です! GNU Radioは、オーディオ、ラジオ信号、その他の信号など、デジタル信号ストリームをリアルタイムで処理する必要がある状況のために特別に作成された信号処理フレームワークです。

関連情報