United Statesからアクセスのようです。言語設定をEnglishに切り替えますか?
Switch to English site
Skip to main content

Raspberry Pi と Pmods でオーディオ処理に挑戦

このプロジェクトでは、Raspberry Pi と Digilent Pmod を使用して、入力オーディオ信号にさまざまなオーディオ エフェクトを適用します。 ユーザー インターフェイスは、効果の程度と種類を制御します。

部品リスト

Qty Product 品番
1 Raspberry Pi 4 B 8GB 182-2098
1 DesignSpark Pmod HAT with 3 Digilent Pmod Sockets for Raspberry Pi 144-8419
1 Digilent Analog-to-Digital Converter Expansion Module 410-064 134-6443
1 Digilent Digital to Analog Converter Expansion Module 410-241 134-6456
1 Digilent LED Expansion Module 410-163 134-6450
1 Digilent Expansion Module 410-135 136-8061
1 Digilent Rotary Encoder Expansion Module 410-117 410-117
1 RS PRO 3.5 mm PCB Mount Stereo Jack Socket, 5Pole 913-1021
1 Digilent Analog Discovery 2 PC Based Oscilloscope, 30MHz, 2 Channels 134-6480
1 Digilent, 240-000 184-0451

序章

今回は、入力された音声信号にオーディオ エフェクト処理を施ことです。 できるだけシンプルにするために、このプロジェクトの概念実証として選択した 2 つのオーディオ エフェクトは、エコー エフェクトとピッチ ベンドです。 これらの影響の性質については、このガイドの後半で説明します。

Block diagram showing circuit operation

Raspberry Pi には、ほぼリアルタイムで入力信号を変更する処理能力があります。 デフォルトでは、これらの信号を取得して再生するために必要な周辺機器がありません。 ただし、Pmod HAT アダプタを使用すると、多種多様なプラグアンドプレイ周辺モジュールである Digilent Pmod をシングルボード コンピュータに簡単に接続できます。 サウンドをキャプチャし、変更してから再生します。 まず、オーディオ信号がアナログ デジタル コンバーター (ADC) に供給されます。 ほとんどの ADC は生のオーディオ入力信号を直接処理できないため、信号の調整が必要になる場合があります。 デジタル信号が処理された後、デジタル アナログ コンバーター (DAC) を使用して、アナログ ドメインに戻す必要があります。 生成された信号をアンプまたはアクティブ スピーカーに送信する前に、再度調整が必要になる場合があります。

オーディオ効果を制御するために、ユーザー インターフェイスを作成します。 このアプリケーションでは、適用されるエフェクトの度合いを設定するロータリー エンコーダー、エフェクトの種類を変更するスイッチ、およびデバイスの状態をリセットするボタンの 3 つのコントロール要素が使用されます。 ユーザーはコントロールの状態に関するフィードバックを必要とするため、8 個の LED で構成される LED バー グラフが表示として使用されます。 電源オンインジケータ LED も便利です。 これにより、外部回路に電力が供給されているかどうかを示すことができます。

ラズベリーパイのセットアップ

このプロジェクトでは、Raspberry Pi OS (バージョン 3.7) にプリインストールされている Python 3 を使用しますが、デフォルトの Python は Python 2 です。簡単にするために、Python 3 をデフォルトのインタープリターとして設定する必要があります。 Raspberry Pi でターミナルを開き、次のように入力します:

sudo update-alternatives --install /usr/bin/python python /usr/bin/python3 1

次に、次のコマンドを使用して、必要な Python パッケージをインストールするか、最新バージョンにアップグレードする必要があります:

pip install numpy matplotlib gpiozero RPi.GPIO spidev --upgrade

 

SPI インターフェイスで制御されるペリフェラルを使用するため、このインターフェイスを有効にする必要があります。 次を使用して構成設定を開きます:

sudo raspi-config

[Interface Options] を選択し、[SPI] で [Yes] を選択してインターフェイスを有効にします。

入力信号

Pmod AD1

Image of a Pmod AD1 board

Raspberry Pi はアナログ信号を直接サンプリングできないため、12 ビットで 1MS/s の ADC である Digilent Pmod AD1 を使用します。 Pmod AD1 は、Analog Devices AD7476Aによって駆動されます。 SPI インターフェイスを介して Raspberry Pi と通信します。

変換は次の式に従います: n=212*Vin/Vref, ここで、n は出力数、Vin は入力電圧、Vref は基準電圧で、供給電圧 (3.3V) に等しくなります。 ただし、ADC は 0V 未満の電圧、または基準電圧よりも高い電圧を処理できません。 ほとんどのデバイスのオーディオ信号の振幅は非常に小さいですが (約 1V)、オフセットは 0V です。 電圧範囲は -1V ~ 1V です。 この問題を解決するには、調整回路を構築する必要があります。

入力信号調整

オーディオ信号の振幅は基準電圧よりもはるかに低いため(2*A<Vref) 、信号に正のオフセットを追加して 0V より上にシフトするだけで十分です。 これを行うには、下の画像に示すように加算増幅器が使用されます。

Input Signal Conditioning Circuit

この構成では、目的のオフセット電圧は抵抗 R4 と R5 によって設定されます:Voffset=VSS*R4/(R4+R5) ここで、VSS は負の電源電圧です。 出力電圧は次の式に従って得られます。 Vout=-(Vin*R2/R1+Voffset*R2/R3)=-(Vin*R2/R1+VSS*R4/(R4+R5)) 、 抵抗 R4 と R5 はオフセット電圧を設定し、抵抗 R1 と R2 は増幅を設定します。 信号は反転していますが、これは回路に影響を与えません。

電源装置

Raspberry Pi のピン 2 と 4 には 5V の電源がありますが、調整回路には負の電源が必要です。 負の電源電圧を得るには、LTM8067 絶縁型 DC-DC コンバータを使用できます。 まず、入力を 5V 電源とグランドに接続します。 次に、コンバータの正の出力ピンを接地します。 入力と出力が絶縁されているため、プラスのピンを接地してもモジュールが短絡することはありません。 ラズベリーパイのグランドと比較して、負のピンの電位は0V未満になります。 非絶縁コンバータでこれを試さないでください! 電圧計を使用して負の出力電圧を測定します。 -5V になるまでドライバーでポテンショメータを回します。

出力信号

Pmod DA3

Image of a Pmod DA3 board

Raspberry Pi には、システム オーディオに使用される 3.5 mm オーディオ ジャックというアナログ出力が 1 つしかありません。 処理されたオーディオ信号を個別に出力するために、Digilent Pmod DA3 が使用されます。 Pmod DA3 は、Analog Devices AD5541Aを搭載した 16 ビット DAC です。 Pmod DA3 は、SPI インターフェイスを介して Raspberry Pi と通信できます。

変換は次の式に従います。 Vout=n*Vref/216, Vout は出力電圧、n は入力番号、 Vref は基準電圧で、2.5V (内部基準) に相当します。 DAC は 16 ビットの符号なし数値しか処理できないため、出力で 0V より低い電圧または Vref より高い電圧を取得することはできません。 ただし、アンプまたはアクティブ スピーカーは、オフセットが 0V で、通常は最大振幅が 1V の入力信号を「待機」するため、出力信号の調整が必要です。

出力信号調整

0 ~ 2.5V の範囲では、少なくとも 1V のオフセットがある場合、1V の振幅の出力信号が可能です。 オフセットは、デカップリング コンデンサとそれに続くボルテージ フォロワによって除去できます。 出力にもローパス フィルターが必要になる場合があります。 ボルテージフォロアの負電源は、スイッチングレギュレータ(フライバックコンバータ)である前述のDC-DCコンバータから取っているため、高周波のスイッチングノイズが発生します。 Raspberry Pi の速度制限により、サンプル レートも制限されます。 サンプル レートを下げると、出力のエッジが鋭くなる可能性があるため、出力周波数の高調波もフィルター処理する必要があります。

人間の話し言葉の母音は最大 2KHz の周波数に達することができますが、子音は 6KHz もの高い周波数に達します。 単純なローパス フィルターを使用する場合、カットオフ周波数を 3KHz から 4KHz の間に設計するのが合理的と思われます。これは、サウンドの大部分が 3500Hz 未満であるためです (ソース).

Output Signal Conditioning Circuit

標準的な抵抗とコンデンサの値を使用すると、フィルタのカットオフ周波数は fc=1/(2*π*R8*C2)=3.4KHzになります。

ユーザーインターフェース

Pmod ENC

Image of a Pmod ENC board

Pmod ENC を使用すると、オーディオ処理をオンにするスイッチ、効果の度合いを設定するロータリー エンコーダー、およびリセット ボタンを使用できます。

Pmod 8LD

Image of a Pmod 8LD board

Pmod 8LD には、低電力ロジック レベルで制御される 8 つの高輝度 LED が含まれています。 これにより、ユーザーにフィードバックを提供できます。

電源インジケータ

Raspberry Pi には電源オン LED がありますが、2 つ目のインジケーターは、調整回路に電源が供給されているかどうかを知らせるのに役立ちます。 電源インジケータを作成するには、LED を電流制限抵抗と直列に 5V 電源に接続するだけです。

Power Indicator Circuit

電流制限抵抗の値は次の式で計算できます: R9=(VCC-VLED)/ILEDここで、VLED は LED の順方向電圧 (通常、赤色 LED の場合は約 1.8V)、ILED は必要な電流です。 LED。 この電流を最大値以下に設定するには、抵抗を選択する必要があります。 LED の明るさは、LED を流れる電流に比例します。 調光インジケータが必要な場合は、より高い値の抵抗を選択する必要があります。

Pmod と Raspberry Pi のインターフェース

Pmod HAT Adapter

Image of Pmod HAT Adapter

Pmod HAT アダプターを使用して、Digilent Pmod を Raspberry Pi に接続できます。 Pmod HAT アダプターは、40 ピン Raspberry Pi GPIO コネクターを 3 つの 2x6 Digilent Pmod コネクター (JA、JB、および JC) に分割し、それぞれを 2 つの別個の 1x6 Pmod コネクターとして使用することもできます (たとえば、JA を JAA に分離できます)。 およびJAB)。 すべての Pmod ポートには、接続された Pmod に電力を供給するためのグランドと 3.3V ピンが含まれています。 すべてのポートを GPIO (General Purpose Input/Output) として使用できますが、一部のポートには追加機能があります。JAA および JBA を使用して Pmod を SPI インターフェイスに接続できます。I2C インターフェイスをポート JBB で使用し、UART を JCA で使用できます。 このアダプターは、Raspberry Pi から直接給電するか、DC バレル ジャックを介して外部 5V 電源から給電することができます (両方を同時に使用しないでください!)。

次の接続をお勧めします:

Pmod HAT Adapter Port Connected Pmod Protocol Used
JAA Pmod AD1 SPI
JAB Pmod ENC GPIO
JBA Pmod DA3 SPI
JC Pmod 8LD GPIO

Pmod AD1 と Pmod ENC の両方を Pmod HAT アダプターの JA ポートに接続するには、Pmod TPH2 12 ポイント テスト ヘッダーを使用できます。

Image of Pmod TPH2 board

フルサーキット

コンディショニング回路、負電源、および電源インジケータをブレッドボードに組み立てたら、5V レールを 40 ピン Raspberry Pi GPIO コネクタのピン 2 に接続し、GND レールをピン 39 に接続します。このようにして、ブレッドボード上の回路は次のようになります。 力を与えられます。 最初の調整回路の出力を Pmod AD1 の A1 チャンネルに接続し、2 番目の調整回路の入力を Pmod DA3 の SMA コネクタに接続します (オス SMA コネクタの代わりに MTE ケーブルをプラグに挿入することもできます)。

The complete circuit

ソフトウェア

前述のように、オーディオ プロセッサを制御するソフトウェアは Python3 で記述されます。 プロジェクトは 6 つのモジュールで構成され、トップダウンのアプローチで提示されます。

main.py

メイン モジュールには、プロジェクトの最も重要な設定が含まれており、他のモジュールを初期化します。 チューニングを容易にするために、すべての重要な数量は、メインモジュールの開始など、アクセス可能な場所に表示する必要があります。

# global variables
spi_clock_speed = int(4e06)   # spi clock frequency in Hz
sample_time = 5e-05  # seconds between samples
buffer_size = 5000  # data points in the buffer
DEBUG = "None"  # "ADC", "DAC", "PROC", "ALL" or "None"
adc_res = 4095  # resolution of the ADC
dac_res = 65535  # resolution of the DAC

Raspberry Pi には、オーディオ入力の受信、オーディオ信号の処理、送信、およびユーザーとの通信という 4 つの重要なタスクがあります。 これらのタスクが次々に実行される場合、2 つの大きな欠陥があります

1. 入力音声と出力音声の間の大きな遅延 (信号が録音、処理、再生される時間)

2. 出力音声の中断。

これらを回避するには、タスクを並行して実行する必要があります。

ユーザー インターフェイスは、非同期イベント (マイクロコントローラーの割り込みなど) を使用してユーザーと通信する gpiozero Python モジュールで実現できます。 メイン モジュールは、これらのイベントにアクションを割り当てるだけです。

# set user interface actions
# increment/decrement a value, when the rotary encoder is rotated
UI.enc.when_rotated = UI.set_value
# reset the value, when the button is pressed
UI.btn.when_pressed = UI.reset_value
# set a flag according to the state of the switch
UI.swt.when_pressed = UI.change_mode
UI.swt.when_released = UI.change_mode

Raspberry Pi 4 Model B にはクアッドコア Cortex-A72 プロセッサが搭載されており、マルチプロセッシング Python モジュールを介してさまざまなプロセッサ コアでタスクを実行できます。 最初のメイン プロセスは、他の子プロセスのみを初期化します。 1 つの子プロセスが入力データを記録し、もう 1 つの子プロセスがデータを処理し、最後の子プロセスがそれを再生します。

出力の中断を避けるために、3 つの共有バッファが使用されます。レコーダ プロセスは 3 つのバッファを順番に埋めます。 最初のバッファがプレーヤー プロセスによって空にされると、プロセス全体が再び開始されます。 データ処理はレコーダを待機し、バッファ内のコンテンツを変更します。

Diagram showing the three shared buffers

共有フラグは、各バッファの状態を通知するために使用されます。

# create shared lists
manager = multiprocessing.Manager()
# 3 buffers to use them in rotation
buffer = manager.list([[], [], []])
# flags to signal aquisition state
get_flag = manager.list([False, False, False])
# flags to signal processing state
set_flag = manager.list([False, False, False])
# flags to signal write-out state
ready_flag = manager.list([True, True, True])

ラッパーは子プロセスを開始し、それらが終了するのを待ちます (プログラムは Ctrl+C で終了します)。

# main part
if __name__ == "__main__":
    UI.reset_value()   # reset counter

    # initialize processes
    acquisition = multiprocessing.Process(target=DI.acquire_data)
    processing = multiprocessing.Process(target=DP.process_data)
    playing = multiprocessing.Process(target=DO.output_data)

    # start threads
    acquisition.start()
    processing.start()
    playing.start()

    # wait for exit condition
    acquisition.join()
    processing.join()
    playing.join()

    UI.reset_value()   # reset counters

    # terminate processes
    acquisition.terminate()
    processing.terminate()
    playing.terminate()

user_interface.py

ユーザー インターフェイス モジュールには、すべてのユーザー インタラクション機能が含まれています。 これらの機能

1. ロータリーエンコーダの状態に応じて変数を設定する

2. この変数に従って LED を点灯させます

3. 異なるスイッチ位置でフラグの状態を変更します (スイッチをプルアップまたはプルダウンする必要があります。そうしないとエッジが検出されないためです)

4. リセット ボタンが押されたときに、すべての値とフラグをリセットします。

def set_value():
    # map the counter between 0 and 1 using the rotary encoder
    global param
    param[0] = enc.steps / (2 * enc.max_steps) + 0.5
    set_leds()  # set LED states
    return
def set_leds():
    global param
    # set the leds on/off according to the counter
    if param[1]:
        led.value = param[0]
    else:
        led.value = -param[0]
    return
def change_mode():
    # switch the flag
    global param
    param[1] = bool(swt.value)
    # force software pull-up/-down
    if param[1]:
        GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)
    else:
        GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
    set_leds()  # set LED states
    return
def reset_value():
    # reset the counter
    global param
    param[0] = 0
    enc.steps = -enc.max_steps  # reset rotary encoder state
    param[1] = bool(swt.value)  # reset switch state
    set_leds()  # reset LED states
    return

このモジュールは、gpiozero Python パッケージのメンバーを利用して、入出力デバイスをより簡単に処理します。

# initialize devices
# Rotary Encoder
enc = RotaryEncoder(19, 21)
btn = Button(20)
swt = Button(18)

# pull down the switch
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

# LEDs
led = LEDBarGraph(16, 14, 15, 17, 4, 12, 5, 6)

受信した値とフラグは共有リストに保存されるため、他のプロセスで使用できます。

# shared user-interface parameters
manager = multiprocessing.Manager()
param = manager.list([0, False])

data_input.py

データ入力モジュールは、spidev Python パッケージを使用して Pmod AD1 との SPI 通信を初期化する役割を果たします。 このモジュールは、受信した 12 ビット データ ワードでバッファを満たし、各取得後に定義済みの時間待機します (2 つのサンプル間の時間が常に同じであることを確認するために、サンプル間で待機する必要があります。そうしないと、ピッチ シフトが発生する可能性があります)。 バッファがいっぱいになったときにフラグを設定して、その状態を他のプロセスに通知します。

# initialize ADC
adc = spidev.SpiDev()
adc.open(SPI_port, CS_pin)
adc.max_speed_hz = main.spi_clock_speed
for _ in range(main.buffer_size):
  # measure start time
  start_time = time.perf_counter()

  # read data bytes
  adc_raw = adc.readbytes(2)
  # recreate the number from the bytes
  adc_number = adc_raw[1] | (adc_raw[0] << 8)
  # insert the number in the buffer
  buff.append(adc_number)

  # check the duration of the operation
  duration = time.perf_counter() - start_time
  # wait if necessary
  if main.sample_time > duration:
    time.sleep(main.sample_time - duration)
# assign buffer and set flags
if main.ready_flag[0]:
  main.buffer[0] = buff
  main.get_flag[0] = True
  main.ready_flag[0] = False
  continue_flag = True
elif main.ready_flag[1]:
  main.buffer[1] = buff
  main.get_flag[1] = True
  main.ready_flag[1] = False
  continue_flag = True
elif main.ready_flag[2]:
  main.buffer[2] = buff
  main.get_flag[2] = True
  main.ready_flag[2] = False
  continue_flag = True

data_output.py

データ出力モジュールは、データ入力モジュールと非常によく似ています。 spidev Python パッケージを使用して、SPI 経由で DAC を制御します。 ただし、出力モジュールは、バッファが処理される前に、3 つのバッファの状態を記述するグローバル フラグをチェックします。 バッファーからのサンプルが DAC に送信された後、待機時間は ADC の待機時間と等しくない場合があります。 これは、各バッファの最初の要素に、(その効果を適用するために) 必要なピッチシフトに関する情報が含まれているためです。

# output buffer
if case != None and len(buff) != 0:
  # calculate the duration of a sample
  # (this is needed because of the pitchbend effect)
  sample_duration = main.sample_time - buff[0]
  # discard the first sample
  # (this contains information about the pitch)
  buff.pop(0)

  # output every sample
  for point in buff:
    # measure start time
    start_time = time.perf_counter()

    # get high byte
    highbyte = point >> 8
    # get low byte
    lowbyte = point & 0xFF
    # send both bytes
    dac.writebytes([highbyte, lowbyte])

    # check the duration of the operation
    duration = time.perf_counter() - start_time
    # wait if necessary
    if sample_duration > duration:
      time.sleep(sample_duration - duration)

data_processing.py

データ処理モジュールは、バッファを処理する前にグローバル フラグをチェックします。 プロセスが同期している必要があります。 このモジュールは、入力バッファを -1 と 1 (正規化された値) の間でマッピングし、コントロール スイッチとロータリー エンコーダの状態に従って正規化されたバッファにエフェクトの 1 つを適用し、DAC の解像度に従って正規化されたバッファを補間します。 必要なタイムシフトを最初の位置に挿入します。 オーディオ エフェクト「エコー」と「ピッチベンド」は、別のモジュールで作成されます。

# normalize values
buff = [interp(element, [0, main.adc_res], [-1, 1]) for element in buff]
# apply audio effect
bend = 0    # store the timeshift if needed
if UI.param[1]:
  bend = AE.pitchbend(UI.param[0], main.sample_time)
else:
  buff = AE.echo(buff, UI.param[0], main.sample_time)
# scale buffer
buff = [round(interp(element, [-1, 1], [0, main.dac_res])) for element in buff]

# insert timeshift
buff.insert(0, bend)

audio_effects.py

このモジュールには、オーディオ エフェクトのプロパティを設定するいくつかの定数が含まれています:

1. echo_mag は、エコー効果のラウドネスを設定します。

2. echo_del は、エコーの最大遅延をミリ秒単位で設定します (より大きな遅延を使用する場合は、バッファー サイズも大きくする必要があり、遅延が大きくなります。遅延が小さいと、エコーの代わりにリバーブ効果が得られる可能性があります)。

3. pitch_bend は、サンプリング周波数と比較したピッチ シフトの最大量を設定します (オーディオが 50 マイクロ秒ごとにサンプリングされる場合、最大シフトが 0.25 の場合、出力サンプル間に 37.5 マイクロ秒の遅延が生じるため、出力信号の周波数は 1.33 倍高くなります)。

echo_mag = 0.8  # echo magnitude between 0 and 1
echo_del = 100  # maximum delay for echo (in ms)
pitch_bend = 0.25   # maximum delay for pitchbend
                    # in % compared to the sample time

最初のエフェクト、pitch_bend は、元のサンプリング時間にロータリー エンコーダーの位置カウンターとピッチ シフトの最大量を乗算することによって、サンプル間の遅延差を計算します。 この値は後でバッファの先頭に挿入されます。

def pitchbend(counter, sample_time):
    # calculate sample delay/advance for pitch bending
    bend = sample_time * counter * pitch_bend
    return bend

エコー エフェクトは元のバッファを取得し、各遅延時間のサンプル カウントを計算して、バッファの先頭にその数の 0 を挿入することにより、そこから遅延バージョンを作成します。 遅延バッファーは、echo_mag 定数に従って減衰され、元のバッファーに追加されます。

def echo(buffer, counter, sample_time):
    # count delay for samples
    counter = round(echo_del * counter / (sample_time * 1000))
    # create dummy buffer
    delay = [0 for _ in range(counter)]
    # shift samples to get the echo
    delayed_buff = delay + buffer
    # add the echo to the original buffer
    result = [buffer[index] + echo_mag * delayed_buff[index]
              for index in range(len(buffer))]
    return result

デバッグ

ハードウェアのデバッグ

Analog Discovery 2 を WaveForms ソフトウェアと共に使用して、ハードウェアをデバッグできます。 AD2 のアナログ入力チャネル 1 のマイナス ワイヤ (オレンジ白のワイヤ) を Raspberry Pi のグランドに接続し、プラスのワイヤ (オレンジ ワイヤ) を使用して電圧を測定し、回路のさまざまなポイントでアナログ信号を表示します。 オシロスコープ機器を使用して波形で結果を表示します。 固定の周波数と振幅の入力信号を使用して、予想される出力を確認します。

視覚化することが推奨されるいくつかの電圧とアナログ信号は、電源の負のレール (約 -5V である必要があります)、入力調整回路 の分圧器の出力 (約 -1.5V である必要があります) です。 )、入力調整回路 の出力 (画像の入力は 50% のラウドネスを持つ 1KHz の正弦波信号です)、

Waveforms screen showing a signwave

DAC の出力 (品質が悪いのは、サンプリング レートが低いためです)、

Wavforms - output of the DAC

出力調整回路の出力、

Wavforms - the output of the output conditioning circuit,

ローパスフィルタ後のデバイス全体の出力。

Waveforms - output of the whole device, after the low-pass filter

1 つまたは複数の信号が想定範囲内にない場合は、ポテンショメータを使用して DC-DC コンバータの変換比を変更する必要があります。 信号の振幅を変更するには、それぞれの抵抗を変更する必要があります。

Pmod HAT アダプターと DAC または ADC の間で Pmod TPH2 を使用して、SPI 信号にテストポイントを設定します。 AD2 のデジタル I/O ピンをテストポイントに接続し、WaveForms でロジック アナライザー機器を使用して、受信/送信データを視覚化します。

Waveforms - showing the select, clock and data lines

ソフトウェアのデバッグ

入力信号と出力信号はオシロスコープまたはロジック アナライザーで簡単に視覚化できますが、仮想的にしか存在しないさまざまなバッファーのステージである内部「信号」があります。 これらのデータ ポイントを視覚化するには、matplotlib.pyplot Python モジュールを使用できます。 モジュールの名前を省略してその機能を示すには、「debug」としてプロジェクトにインポートできます。

# display the buffer if needed
if main.DEBUG == "ADC" or main.DEBUG == "ALL":
  debug.plot(buff)
  debug.show()

チューニング

アプリケーションのパフォーマンスは、いくつかの重要なパラメーターに依存します。 プロジェクト全体で最も重要な 2 つの値は、サンプリング時間とバッファ サイズです。 サンプリング時間を短縮すると、出力の品質と帯域幅 (ローパス フィルターの前) が向上しますが、各バッファーが満たされるのに必要な時間も増加します。 バッファがいっぱいになるのが遅すぎると、出力が中断されます。 これはバッファサイズを小さくすれば改善できますが、バッファサイズを小さくするとエコー効果がかからなくなり、ピッチベンドのタイミングの問題も出てきます。 サンプリング時間が非常に短いと、出力オーディオのピッチ シフトがランダムに現れる場合があります。 解決策は、優れたオーディオ品質と中断のない操作のバランスを見つけることです。

結果

50 マイクロ秒のサンプリング時間と 5000 サンプルのバッファーでのいくつかの結果:

Input audio - female voice

Output audio - female voice

Female voice, 50% echo

Female voice, 100% echo

Female voice, 50% pitch shift

Female voice, 100% pitch shift

Input audio - male voice

Output audio - male voice

Male voice, 50% echo

Male voice, 100% echo

Male voice, 50% pitch shift

Male voice, 100% pitch shift

 

                                                                                            

ダウンロード

awong さんはまだ自己紹介を入力されていません...
DesignSpark Electrical Logolinkedin