Python:ScipyでFFTを行う

scipyのfftメソッドは二つありますがscipy.fftを使うことが推奨されてるようです。

コード

import matplotlib.pyplot as plt
import numpy as np
from scipy.fft import fft, fftfreq

f0 = 1000
fs = 96000
N = 5000
addnum = 5.0

def create_sin_wave(amplitude,f0,fs,sample):
    wave_table = []
    for n in np.arange(sample):
        sine = amplitude * np.sin(2.0 * np.pi * f0 * n / fs)
        wave_table.append(sine)
    return wave_table

# 信号波形の生成
wav = create_sin_wave(1.0,f0,fs,N)

# FFTの実行
X = fft(wav[0:N])
freqList = fftfreq(N, d=1.0/ fs)
amplitude = np.abs(X)/(N/2)

# 波形を描画
plt.subplot(211) 
plt.subplots_adjust(hspace=0.5)
plt.plot(range(0,N), wav[0:N],label = "wave1")
plt.axis([0, 500, -1.0, 1.0])
plt.xlabel("sample")
plt.ylabel("amplitude")

# 振幅スペクトルを描画
plt.subplot(212)
plt.plot(freqList, amplitude, marker='.', linestyle='-',label = "fft plot")
plt.axis([0, 20000, 0, 2])
plt.xlabel("frequency [Hz]")
plt.ylabel("amplitude")

plt.show()

FFT結果

f:id:gsmcustomeffects:20220305222226p:plain

Python:リングモジュレーターの実装①



今回はリングモジュレータを実装していく。

リングモジュレータ

入力と関係ない音程を出すエフェクター。マルチ・エフェクターに組み込まれていることもある。かなり前衛的な演奏ができる。(weblio引用

音としてはこんな感じ

元の音

エフェクト音

理論としては入力の音に対してある周期波形を乗算してめちゃくちゃな音程にするエフェクトです。
変調波形を正弦波として表すとこのような感じ

  • out[ n] = in[ n] \times Asin2\pi f_{0} t
  • t = n / fs

A:正弦波の振幅
f0:正弦波の周波数[Hz]
n:その時のサンプル
fs:サンプリング周波数[Hz]

エフェクトの波形

f:id:gsmcustomeffects:20180801023157p:plain

  • 上段:入力音
  • 中段:変調波形(200Hzの正弦波)
  • 下段:出力音

かけている正弦波の影響を受けて波形が変形している。

ソースコード

処理の流れはこのようになる

  1. 元データがステレオなのでwavファイルをLRにわける
  2. モノラル化する(LRを半分にして加算)
  3. 正弦波を作る
  4. エフェクトをかける
  5. wavに格納しなおす
import wave
import audio_func as af
import scipy
import struct
import numpy as np
from pylab import *

wf = wave.open("GS04.wav", "r")#wav 扱うならお決まりのやつ
num_data = scipy.fromstring(wf.readframes(wf.getnframes()),dtype = "int16") / 32768.0#正規化

if(wf.getnchannels() == 2):
    left = num_data[::2]#1 スライス
    right= num_data[1::2]
    in_data = left*0.5 + right*0.5#2ステレオモノラル化
    #1:スライスの説明
    #a[1,2,3,4,5]ていうリストがあったとして
    #a[::2]  -> 1,3,5
    #a[1::2] -> 2,4

    #2:ステレオ->モノラル化
    #もともとギターの録音で左右に同じ音ふってるのでLR分解して半分にして足せば同じようなもん

fs = wf.getframerate()
AM_WAVE = []#振幅変調波形のメモリ確保
f0 = 200      #正弦波の周波数[Hz]

#フレームの長さ分だけ正弦波を作る
for n in np.arange(wf.getnframes()):
    sine = 0.2 * np.sin(2 * np.pi * f0 * n / fs)
    AM_WAVE.append(sine*(1/0.2))

#リングモジュレータなので振幅変調する
out_data = in_data * AM_WAVE
subplots_adjust(hspace=0.5)
subplot(311)
plot(in_data[0:6000],label="input")
legend()
subplot(312)
plot(AM_WAVE[0:6000],"red")
subplot(313)
plot(out_data[0:6000],label="output")
legend()
show()
#正規化したデータを元に戻す
out_data = [int(x * 32768.0) for x in out_data]
out_data = struct.pack("h" * len(out_data), *out_data)
#af.play(out_data,wf.getsampwidth(),1,wf.getframerate()) #再生
af.save(out_data, fs,1,"ring.wav")

audio_funcは一例です。(かなり雑な実装なため

import wave
import pyaudio
from pylab import *

def printWaveInfo(wf):
    """WAVEファイルの情報を取得"""
    print("チャンネル数 : "+ str(wf.getnchannels()))
    print("サンプル幅 : "+ str(wf.getsampwidth()))
    print("サンプルレート : "+ str(wf.getframerate()))
    print("フレーム数 : "+ str(wf.getnframes()))
    print("総パラメータ(一括表示用) : "+ str(wf.getparams()))
    print("再生時間 : "+ str(float(wf.getnframes()) / wf.getframerate()))

def play (data,sampleWidth,Channel,sampleRate):
    # ストリームを開く
    p = pyaudio.PyAudio()
    stream = p.open(format=p.get_format_from_width(sampleWidth),
                    channels=Channel,
                    rate=int(sampleRate),
                    output= True)
    # チャンク単位でストリームに出力し音声を再生
    chunk = 1024
    sp = 0  # 再生位置ポインタ
    buffer = data[sp:sp+chunk]
    while buffer != '':
        stream.write(buffer)
        sp = sp + chunk
        buffer = data[sp:sp+chunk]
    stream.close()
    p.terminate()


def save(data, fs,Channel,filename):
    """波形データをWAVEファイルへ出力"""
    wf = wave.open(filename, "w")
    wf.setnchannels(Channel)
    wf.setsampwidth(2)
    wf.setframerate(fs)
    wf.writeframes(data)
    wf.close()

Python:ステレオwavファイルをLRに分ける

基礎編です。



信号処理をやって行くにあたりまずは入力となるwavファイルについて知っておく必要がある。
フォーマットに関してはここを読んでほしい
http://sky.geocities.jp/kmaedam/directx9/waveform.html

まあ簡単に言えばヘッダー情報の後はLRLRLRと信号が並んでいる感じ。
I2Sデータもそうだが基本的に信号処理ルーチンを組むならこういったデータを整列して*1いく必要がある。


というわけで2チャンネルのwavファイルを用意してコードを書いてみた
wave_lr.py

import wave
import matplotlib.pyplot as plt
import audio_func as af
import scipy

wf = wave.open("GS03.wav", "r")
af.printWaveInfo(wf)  # デバッグ用
data = wf.readframes(wf.getnframes())
num_data = scipy.fromstring(data,dtype = "int16")

if(wf.getnchannels() == 2):
    left = num_data[::2]
    right= num_data[1::2]

    #スライスの説明
    #a[1,2,3,4,5]ていうリストがあったとして
    #a[::2]  -> 1,3,5
    #a[1::2] -> 2,4

# left channel
plt.subplot(2, 1, 1)
plt.plot(left,label="left")
plt.legend()

# right channel
plt.subplot(2, 1, 2)
plt.plot(right,label="right")
plt.legend()
plt.show()

audio_func.py

def printWaveInfo(wf):
    """WAVEファイルの情報を取得"""
    print("チャンネル数 : "+ str(wf.getnchannels()))
    print("サンプル幅 : "+ str(wf.getsampwidth()))
    print("サンプルレート : "+ str(wf.getframerate()))
    print("フレーム数 : "+ str(wf.getnframes()))
    print("総パラメータ(一括表示用) : "+ str(wf.getparams()))
    print("再生時間 : "+ str(float(wf.getnframes()) / wf.getframerate()))

結果がこんな感じ
もともとモノラルなギターを左右に振ってるだけなので同じ波形が出てくる
f:id:gsmcustomeffects:20180730073550p:plain

コンソール画面

チャンネル数 : 2
サンプル幅 : 2
サンプルレート : 44100
フレーム数 : 196475
総パラメータ(一括表示用) : _wave_params(nchannels=2, sampwidth=2, framerate=44100, nframes=196475, comptype='NONE', compname='not compressed')
再生時間 : 4.455215419501134

補足

フレーム数 : 196475と出ているがこれはwavとしてのフレームのためLR合わせたときのもの

num_data = scipy.fromstring(wf.readframes(wf.getnframes()),dtype = "int16") / 32768.0

とした場合二倍の392950がサイズとなる
f:id:gsmcustomeffects:20180731013557p:plain

上記の例ではこれを分解してるので
Lのサイズ->196475
Rのサイズ->196475

*1:interleaveを外す、解くとか言われてる

logicool K380の紹介

最近キーボードがタンブラー転倒により水没したので買い替えました。

Amazonで2700円ぐらいでした。


最近机の上にマイクロスコープだったりリワークステーションだったが増えてきて邪魔になりつつあったのでBluetoothかつ小ぶりなものを選んだ。

結構使いやすいしアプリから電池残量を確認できたりしてうれしい。

その他半田とかをするときにモニター台の下にすっぽり格納できて机を広く使える。
f:id:gsmcustomeffects:20180513051034j:plain
モニター台座はこれを使ってる(画像クリックでリンク)

横にUSBとACコンセントがあって助かる。

2018開発環境の紹介

ツールだったり調達先だったりをまとめてくれと前々から言われていたので簡単にまとめてみようと思う。
ハードウエア環境、基板メーカー、部品調達先、ソフトウエア環境な感じで紹介していく感じにしようかなと
というわけで今回はハードウエア面のことをやろうと思う。


ハードウエア

YIHUA 992DA+

まずはコテ
YIHUAの992DA+
f:id:gsmcustomeffects:20180402201521p:plain

こいつはAliexpressのYIHUAストアでセールをやっているときに180ドルぐらいで手に入れた。
コテ部分には温調機能とスモークアブソーバーがついているためフラックスを大量に使ったりするときに煙が舞わなくて良い。
海外製ということで消耗品の購入までのリードタイムが長すぎるとか心配する人もいるだろう。
なんと小手先はHAKKOのが使えるw
f:id:gsmcustomeffects:20180402211329p:plain

小手自体は流石に無理なのでこいつ(20ドル程度でヒーターはHAKKOらしい)
https://ja.aliexpress.com/store/product/YIHUA-907I-soldering-iron-for-weldering-machine-tools/401349_1853158228.html?spm=a2g11.12010612.0.0.569f60e0pG8BaX
f:id:gsmcustomeffects:20180402211141p:plain

その他ホットエアーがついている。
その他とは言ってもこれがついているので選んだところが大きい。

中華系サイトで探せば互換品がいくつもあるがこいつについてるホットエアーは結構しっかりしていて安物とは違う感じがある。
Twitterでよく耳にする風が強すぎてチップ部品が飛んでいく等の問題はないレベルまで風量を下げられる。
その他温度も400度ぐらいまで上がる(推奨はしないが)ので結構綺麗にリワークできる。

それ以外の詳細スペックは以下を参照されたい
ja.aliexpress.com

ANDONSTAR ADSM201

普通のHDMIマイクロスコープ
自身にも液晶がついてるがまあ補助程度基本はHDMIで使う方がいいだろう。
f:id:gsmcustomeffects:20180402205524p:plain
SMDパーツの半田付けやリフローのショートチェックに使っている。

あとは基板のリフローの接写とかそういうのにも使える。

山善ホットプレート

ホットプレートリフロー用に購入したもの。
安いので簡単な施策には必須。

基板焦げになりやすいという欠点があるので上にアルミブロックとか置くとヒートショックを避けれる。
参考までにツイート

ホットプレートでもここまで綺麗にできるぞっていう自慢

ピンセット

ピンセットはamazonで買える安いやつ。

先曲がりとストレートが一個づつあるといいと思います。

ディスペンサ

注射器とかシリンジとかその類の話

使用用途としてはフラックス添加とかステンシルがない時のペースト半田印刷

参考ツイートをいくつか貼る。



使っているのはここの青いチップ
https://ja.aliexpress.com/store/product/0-5-Tubing-Length-100-PCS-X-22G-TE-Premier-Dispensing-Tips-dispensing-tips-dispensing-needle/1503742_32627886559.html?spm=a2g11.12010612.0.0.141b46f20TfhQ0

本体はこれ
https://ja.aliexpress.com/store/product/3CC-Manual-Glue-Dispensing-Syringe-Applicator-for-precisely-dispensing-pastes-sealants-and-epoxies/1503742_32219596623.html?spm=a2g11.12010612.0.0.306fb73dh7uskB

本体は好きなの選べばよいがチップを装着する部分がねじ込み式のロックがあるやつを選んだほうがいい。
理由として半田ペーストの粘土が思ったより高いためロックがないタイプのを使うと先端が飛んでいって悲惨なことになる。(僕はこれでなんども萎える経験をしました。)

そのほか補足をしておくと
先端はgという単位で扱われていて数字が大きくなるほど細い
f:id:gsmcustomeffects:20180402223017p:plain

よくわからなければこのようにセットのを買ってみて自分好みのを探すのも良いだろう。
https://ja.aliexpress.com/store/product/1-4-Tubing-Length-100-PCS-TE-Premier-Dispensing-Tips-dispensing-needles-Glue-Dispensing-Tip/1503742_32625074730.html?spm=a2g11.12010612.0.0.45062766LsQwVW


余談だがフラックスを添加するにはこのぐらいの太さがいい(ペーストより多めに添加するため)
https://ja.aliexpress.com/store/product/16G-2-Dispensing-Needles-Tips-For-Glue-100pcs-bag/1503742_32389438536.html?spm=a2g11.12010612.0.0.45062766BYLuVg


ペースト半田およびフラックス

リフローに使う半田と金属表面活性化のためのフラックス

半田はここのを使っている。
https://ja.aliexpress.com/store/product/Leaded-SMT-solder-paste-LED-dedicated-solder-paste-Sn63Pb37-500-grams/2942090_32805542877.html?spm=a2g11.12010612.0.0.405479aeiF6tRC

このケースは結構見るがこのストアは色々な種類を扱っており安心感がある。(まあ他のだと製造日がクソみたいの送ってきて期限がすぎてたりする。)

使用感はこんなもん(フラックスで多少の粘度調整を入れている

Twitterではこのタイプ使ってる人をよく見るけど内蓋のパッキンがないのですぐカピカピになる。
f:id:gsmcustomeffects:20180402224002p:plain

僕の知り合いのあろえさんとかはこれ使ってるらしいけどあの人みたいに一回で結構使わない人だとこれよくない説はある。
無論上記の500gも微妙なところではあるが今の所1年経っても動画のように粘度は低いままだ。

ちなみに鉛フリーも売っている。
https://ja.aliexpress.com/store/product/ECO-solder-paste-M705-s101zh-s4-lead-free-solder-paste-containing-silver-Sn96-5-ag3cu0-5/2942090_32826369659.html?spm=a2g11.12010612.0.0.bed09537RopKNT

見た目はSMICのeco solderっぽい。
ag3.0%って結構いいやつっぽいのでlead freeならこれかな。

無論こっちでもいいのだけれど
https://ja.aliexpress.com/store/product/High-temperature-lead-free-SMT-solder-paste-BGA-solder-paste-special-mobile-phone-repair-Sn99-Ag0/2942090_32807755672.html?spm=a2g11.12010612.0.0.bed09537XlqVBP

ちなみにビスマス含有の場合鉛とか混ざるとクラックがやばいらしいので注意が必要だ。

次にフラックスの話。

コテ使う場合は基本液体の方使ってる。

なぜかでかいの使ってる。
前勤めてた会社で一個もらったのでこんなにでかい。

長くコテ当てたりリフローする場合はこっち使ってる
吉田 YT 60 bga はんだフラックスペーストはんだ 100 グラム SMT を Reballing|flux paste solder|solder flux pasteflux paste - AliExpress


あとはこれ(多分中はあんまし変わらない
Pjlsw はんだペースト,ミルキーホワイトNC 559 ASM g,bga,はんだフラックス,送料無料|solder flux paste|flux pastebga solder flux paste - AliExpress

元ネタ(純正のわけがないw)はamtechのフラックスなんですけど洗浄ありとか無洗浄とかあるけどケースの色で分けてるんかね?(その辺はわかりませんのでとりあえず洗浄することにしてる。

最後にリムーバー

無水エタ使ってる時期もあったけど残渣の結晶化で白い粉が基板に付着するのでトルエンとかキシレンとか入ってるやつの方がいいと思うということでこっちに変えました。
オススメしていただいたざわざわ(@ZawaZawah)さんありがとうございます。

まとめ

今回はツールを紹介した。
万人にオススメできるものではないがsmtで試作をする場合のツールの一つとしてみてくれたら嬉しい。

自作エフェクタデザインのぺーじ



ここ最近エフェクターの創作アイデアをゆきょんくん(@Yukyoooon)と一緒にやってるのでそれの紹介
僕が適当に構図指定するとそれを送ってくれるので非常に助かってます。

デザインは上から順に新しいのがのるはず

はやく形にしたいなぁ
f:id:gsmcustomeffects:20180325011552p:plain

続きを読む