

Pythonでnumpy配列同士を和の演算すると各要素の和になるということらしく表示されるグラフに影響が出てしまいました。

それを回避するためにnumpyの何かしらを用いて音データの重ね合わせをしたいです。  
song1に10秒の曲データ、song2に1秒のノイズデータがあるとして  
song1の5-6秒の1秒間にノイズを重ね合わせて、それを反映させた音を聴けるようにするにはどうすればよいのでしょうか?

[code]

    mixmusic=np.insert(song1,song1[5*sr:6*sr],song2)
    IPython.display.Audio(mixmusic, rate=sr) #完成音データを聞ける様に
    
[/code]

など、様々試してみましたが、どうやってもノイズが10秒の曲の冒頭や最後に挿入されてしまいます。

以下のノイズ波形とsong1の波形を互いに影響が及ばないように重ね合わせたいです。  
ノイズの最大値はsong1の最大値と一致させるという処理をしています。  
単純にsong1[5 _sr:6_ sr]+=song2のようにすると振幅値がsong1とsong2の最大値を超えてしまうのでそうならないようにしたいです。

[![song2\(ノイズの波形\)](https://i.stack.imgur.com/egCOU.png)](https://i.stack.imgur.com/egCOU.png)

[![song1の波形](https://i.stack.imgur.com/A2FPW.png)](https://i.stack.imgur.com/A2FPW.png)

[![単純な和で実現させた結果](https://i.stack.imgur.com/KSZ97.png)](https://i.stack.imgur.com/KSZ97.png)


CC BY-SA 4.0
2020-07-24T14:17:38.867
68918
2020-07-25T02:39:09.133
2020-07-25T02:39:09.133
41237
41237
question
python numpy matplotlib
Numpyでの音データ同士の重ね合わせ


10秒の曲データsong1と、1秒のノイズデータsong2がある。  
song1の5-6秒の1秒間にノイズ(song2)を重ね合わせたい。  
という事ですから、

出来上がった曲は  
0-5秒 song1の0-5秒と同じ （なにも変化させていない）  
5-6秒 song1の5-6秒とsong2とを重ね合わせたもの  
6-10秒 song1の6-10秒と同じ （なにも変化させていない）  
になるはずです。

song1の0-5秒と、song1の5-6秒、song1の6-10秒は、  
song1[0:5 * sr]、song1[5 * sr : 6 * sr]、song1[6 * sr : 10 *
sr]のように、song1のスライスで得られます。

song1[0 : 5 * sr]と、song1[5 * sr : 6 * sr]とsong2とを重ね合わせたものと、song1[6 * sr : 10 *
sr]の３つを連結すれば、質問者が望んでいる曲データになるのではないでしょうか？


CC BY-SA 4.0
2020-07-25T01:43:10.020
68928
2020-07-25T01:43:10.020
217
68918
answer


挿入するwavファイルの先頭と末尾に[無音区間を入れて](https://stackoverflow.com/a/32477869/8248751)、行列の要素数を揃えた上で[合成する](https://stackoverflow.com/a/52074839/8248751)こと自体は可能です。

[code]

    import numpy as np
    from scipy.io import wavfile
    
    rate = 44100
    pad_start_sec = 5 # データ挿入位置
    
    # サンプルデータ(sin.wav, noise.wav)作成
    def create_samplings():
        seconds = 10 # 正弦波データ10秒
        sin_wave = [i / 20 for i in range(0, rate * seconds)] # i/20は低音に抑えるため
        sin = np.int16(np.sin(sin_wave) * 32767)
        wavfile.write('sin.wav', rate, sin)
        noise = np.int16(np.random.uniform(-0.1, 0.1, rate) * 32767) # ノイズデータ 1秒
        wavfile.write('noise.wav', rate, noise)
    
    create_samplings()
    fs, sin = wavfile.read('sin.wav')
    _, noise = wavfile.read('noise.wav')
    
    # ノイズの前後に無音区間を追加
    pad = np.int16(np.zeros(sin.size) * 32767)
    pad_start = rate * 5
    pad[pad_start: pad_start + noise.size] = noise
    # 合成して書き出し
    z = sin + pad
    wavfile.write('out.wav', fs, z)
    
[/code]

しかしライブラリを使える環境ならば、[pydub](http://pydub.com/)などのライブラリ利用をお勧めします。

[pydub.AudioSegment.overlay](https://github.com/jiaaro/pydub/blob/master/API.markdown#audiosegmentoverlay)を使うサンプルコード

[code]

    from pydub import AudioSegment
    
    sin = AudioSegment.from_file("sin.wav")
    noise = AudioSegment.from_file("noise.wav")
    output = sin.overlay(noise, position=5000)
    output.export("out.wav", format='wav')
    
[/code]


CC BY-SA 4.0
2020-07-25T01:43:37.563
68929
2020-07-25T01:43:37.563
9820
68918
answer