実現したいこと
ここに実現したいことを箇条書きで書いてください。
- fft = fftpack.fft()でフーリエ変換したデータを
python
1def idx_of_the_nearest(x, y): 2 idx = np.argmin(np.abs(np.array(x) - y)) 3 return idx 4 5x = [1, 1 ,1 ,0.5 ,2 ,3 ,-1] 6y = 0.8 7n = idx_of_the_nearest(x, y)
みたいなかんじなプログラムで特定の周波数だけの音声データになるように編集したいのですが、フーリエ変換して得たデータの数値一つ一つ取り上げて編集する方法がわかりません
元のプログラムではfor f in range(0, int(len(fft)/2)):を使っていたのですが、shift_frequencyをどう代用すればスケール変換ができるかわかりませんでした
元のプログラムは
python
1shift_frequency = 1500 # シフトさせる周波数(Hz) 2shift = int(shift_frequency*len(fft)/FrameRate) #周波数→データインデックスにスケール変換 3for f in range(0, int(len(fft)/2)): 4 if( (f+shift > 0) and (f+shift < int(len(fft)/2)) ): 5 fft[f] = fft_original[f+shift] 6 fft[-1*f] = fft_original[-1*f-shift] 7 else: 8 fft[f] = 0 9 fft[-1*f] = 0 10fft_amp = np.abs(fft / (N / 2))
でデータ内の音の周波数を1500Hz高くなるよう編集するプログラムです
前提
google colabでプログラミングしています
該当のソースコード
python
1# 音声編集ソースコード 2 3 # 必要なモジュールをインポート 4from pydub import AudioSegment 5import matplotlib.pyplot as plt 6import numpy as np 7from scipy import fftpack 8from scipy.io.wavfile import write 9import copy 10 11 # 自動的に増幅する振幅を計算する関数 12def Auto_amp_coefficient(original_data, edited_data): 13 sampling_num = 10000 #サンプル数.増やすと精度が上がる 14 sample = np.random.randint(0, len(original_data), sampling_num) 15 ''' 16 amp_sum = 0 17 for s in sample: 18 amp_sum += abs(original_data[s])/abs(edited_data[s]) 19 amp = amp_sum/sampling_num 20 ''' 21 amp = max(original_data)/max(edited_data) 22 23 return amp 24 25# ファイルの読み込み 26sourceAudio = AudioSegment.from_wav("/content/drive/MyDrive/Piano-A5.wav") 27 28#動画の長さを取得 29AudioLength = sourceAudio.duration_seconds 30print('音声データの秒数', AudioLength, 'sec') 31 32#音声のフレームレート 33FrameRate = sourceAudio.frame_rate 34print('フレームレート', FrameRate, 'Hz') 35 36# 音声データをリストで抽出 37wave = sourceAudio.get_array_of_samples() 38 39N = len(wave) 40print("データ個数", N) 41 42dt = 1/FrameRate # = AudioLength/N 43print('dt', dt, 'sec') 44 45# FFT処理 46fft = fftpack.fft(wave) # FFT(実部と虚部) 47 48#編集 ------------------------------------- 49 50 # 元データを保管 51fft_original = copy.copy(fft)
ここから編集をするつもりです
試したこと
知識不足で、試せたことがありません
python
1def idx_of_the_nearest(x, y): 2idx = np.argmin(np.abs(np.array(x) - y)) 3return idx 4 5for f in range(0, int(len(fft)/2)): 6x = [#数値を入れる] 7y = 8n = idx_of_the_nearest(x, y)
でフーリエ変換したデータの周波数をyに代入して編集したいのですがどう代入すればいいのかわかりませんでした
補足情報(FW/ツールのバージョンなど)
Python 3.10.12
numpy 1.23.5
scipy1.10.1
pythonのコードの一番最初の行のすぐ上に
```python
だけの行を追加してください
また、pythonのコードの一番最後の行のすぐ下に
```
だけの行を追加してください
または、
https://teratail.storage.googleapis.com/uploads/contributed_images/56957fe805d9d7befa7dba6a98676d2b.gif
を見て、そのようにしてみてください
現状、「該当のソースコード」以外のコードがとても読み辛いです
質問に載せるコードの全てに上記をやってくれたら、他人がコードを読みやすくなり、コードの実行による現象確認もやりやすくなるので、回答されやすくなると思います
質問や、Make_Kawaii2さんの回答へのコメントを見ても、質問者さんがやりたいことが分かりません
たとえば、
import numpy as np
from scipy.fft import fft, fftfreq
# データを作成
wave = np.random.randn(10)
dt = 0.1 # サンプリング周期(秒)
# FFT
F = fft(wave)
freq = fftfreq(len(wave), d=dt)
を実行したら、周波数が「freq」に格納されます
print(freq)
# [ 0. 1. 2. 3. 4. -5. -4. -3. -2. -1.]
上記が元の周波数だとしたら、それをどうしたいのでしょうか?
> データ内の音の周波数を1500Hz高く
なら、
[ 0. 1. 2. 3. 4. -5. -4. -3. -2. -1.]
↓
[1500., 1501., 1502., 1503., 1504., -1505., -1504., -1503., -1502., -1501.]
としたいのかなぁ、とか想像できますが、
> 特定の周波数だけの音声データになるように編集したい
> 特定の周波数を集めたリスト内で一番近い周波数に変換
の意味が分かりません
FFT後の周波数の数は元データ数と同じなので、たとえば上記例の場合は10個あります
「特定の周波数を集めたリスト」の数は、元の周波数の数と同じだけあるのでしょうか?
上記がyesの場合ですが、たとえば、FFT後の周波数が
[ 0. 1. 2. 3. 4. -5. -4. -3. -2. -1.]
で、「特定の周波数を集めたリスト」が
[ 0. , 1.3, 2.6, 3.9, 5.2, -6.5, -5.2, -3.9, -2.6, -1.3]
の場合、元の周波数の内の「2.0」と「3.0」に近いのはどちらも「2.6」ですが、そのような場合はどうするのでしょうか?
リストの中にピアノの音階の周波数を入れて、音声データをドレミの音程に変換するプログラムを考えております。
「特定の周波数を集めたリスト」は
for f in range(0, int(len(fft)/2)):
x=[1,2,3]
y=
n = idx_of_the_nearest(x, y)
のようにして元の周波数と同じ数を用意するつもりです。
また、このやり方ならば周波数を一つずつ編集していくのでおそらくリスト内の数値の取り合いにはならないと考えております。
あなたの回答
tips
プレビュー