%23%20gallery_category%3A%20FDN%20Design%20%26%20Analysis%0A%0Aimport%20marimo%0A%0A__generated_with%20%3D%20%220.23.13%22%0Aapp%20%3D%20marimo.App()%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20marimo%20as%20mo%0A%0A%20%20%20%20return%20(mo%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%20Time%20Varying%20FDN%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20Example%20for%20time-varying%20matrices.%3Cbr%2F%3E%0A%20%20%20%20Process%20a%20musical%20sound%20with%20a%20time-varying%20FDN%20reverberation.%20Different%0A%20%20%20%20options%20include%20slow%20and%20fast%20time-variation.%0A%0A%0A%20%20%20%20Reference%3A%20*Schlecht%20and%20Habets%202015%20%3A%20%22Practical%20Considerations%20of%20Time-Varying%0A%20%20%20%20Feedback%20Delay%20Networks%22*%20%3Cbr%2F%3E%0A%20%20%20%20Reference%3A%20*Schlecht%20and%20Habets%202015%20%3A%20%22Time-varying%20feedback%20matrices%20in%20feedback%20delay%20networks%0A%20%20%20%20and%20their%20application%20in%20artificial%20reverberation%22*%0A%0A%20%20%20%20Original%20MATLAB%3A%20Sebastian%20J.%20Schlecht%2C%20Saturday%2C%2028%20December%202019%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_()%3A%0A%20%20%20%20import%20numpy%20as%20np%0A%20%20%20%20import%20scipy.linalg%20as%20la%0A%0A%20%20%20%20import%20pyFDN%0A%20%20%20%20from%20pyFDN.auxiliary.acoustics%20import%20one_pole_absorption%0A%20%20%20%20from%20pyFDN.dsp.time_varying_matrix%20import%20TimeVaryingMatrix%0A%20%20%20%20from%20pyFDN.generate.random_orthogonal%20import%20random_orthogonal%0A%20%20%20%20from%20pyFDN.process%20import%20process_fdn%0A%0A%20%20%20%20return%20(%0A%20%20%20%20%20%20%20%20TimeVaryingMatrix%2C%0A%20%20%20%20%20%20%20%20la%2C%0A%20%20%20%20%20%20%20%20np%2C%0A%20%20%20%20%20%20%20%20one_pole_absorption%2C%0A%20%20%20%20%20%20%20%20process_fdn%2C%0A%20%20%20%20%20%20%20%20pyFDN%2C%0A%20%20%20%20%20%20%20%20random_orthogonal%2C%0A%20%20%20%20)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20Object%20Initialization%20%26%20Audio%20Loading%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(mo)%3A%0A%20%20%20%20sound_selection%20%3D%20mo.ui.dropdown(%0A%20%20%20%20%20%20%20%20options%3D%5B%22sine%22%2C%20%22melody%22%5D%2C%0A%20%20%20%20%20%20%20%20value%3D%22melody%22%2C%0A%20%20%20%20%20%20%20%20label%3D%22Sound%22%2C%0A%20%20%20%20)%0A%20%20%20%20mo.output.replace(sound_selection)%0A%20%20%20%20return%20(sound_selection%2C)%0A%0A%0A%40app.cell%0Adef%20_(mo%2C%20np%2C%20pyFDN%2C%20sound_selection)%3A%0A%20%20%20%20np.random.seed(1)%0A%0A%20%20%20%20%23%20init%20source%20signal%0A%20%20%20%20mode%20%3D%20sound_selection.value%0A%0A%20%20%20%20if%20mode%20%3D%3D%20%22sine%22%3A%0A%20%20%20%20%20%20%20%20fs%20%3D%2048000%0A%20%20%20%20%20%20%20%20duration%20%3D%204%0A%20%20%20%20%20%20%20%20time%20%3D%20np.linspace(0%2C%20duration%2C%20duration%20*%20fs)%5B%3A%2C%20None%5D%0A%0A%20%20%20%20%20%20%20%20synth1%20%3D%200.5%20*%20np.sin(time%20*%20440%20*%202%20*%20np.pi)%0A%20%20%20%20%20%20%20%20synth2%20%3D%200.5%20*%20np.sin(time%20*%20660%20*%202%20*%20np.pi)%0A%0A%20%20%20%20%20%20%20%20%23%20Concatenate%20columns%20horizontally%0A%20%20%20%20%20%20%20%20synth%20%3D%20synth1%20%2B%20synth2%0A%20%20%20%20%20%20%20%20synth%5B-2%20*%20fs%20%3A%2C%20%3A%5D%20%3D%200.0%0A%0A%20%20%20%20elif%20mode%20%3D%3D%20%22melody%22%3A%0A%20%20%20%20%20%20%20%20synth%2C%20fs%20%3D%20pyFDN.load_audio(%22synth_dry.wav%22)%0A%20%20%20%20%20%20%20%20print(f%22Loaded%20%7Blen(synth)%7D%20samples%20at%20%7Bfs%7D%20Hz%20(%7Blen(synth)%20%2F%20fs%3A.2f%7D%20s)%22)%0A%0A%20%20%20%20%20%20%20%20samples%20%3D%20np.arange(len(synth))%0A%20%20%20%20%20%20%20%20time%20%3D%20(samples%20%2F%20fs)%20*%201000%20*%201000%0A%0A%20%20%20%20_audio_src%20%3D%20synth.T%20if%20synth.ndim%20%3D%3D%202%20else%20synth%0A%20%20%20%20mo.vstack(%5Bmo.audio(_audio_src%2C%20fs)%5D)%0A%20%20%20%20return%20fs%2C%20synth%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20Define%20FDN%3A%20Signal%20Dimensionality%20%26%20Formatting%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(la%2C%20np%2C%20random_orthogonal)%3A%0A%20%20%20%20N%20%3D%208%0A%20%20%20%20num_input%20%3D%201%0A%20%20%20%20num_output%20%3D%202%0A%0A%20%20%20%20input_gain%20%3D%20la.orth(np.random.randn(N%2C%20num_input))%0A%0A%20%20%20%20random_matrix%20%3D%20np.random.randn(num_output%2C%20N)%0A%20%20%20%20output_gain%20%3D%20la.orth(random_matrix.T).T%0A%0A%20%20%20%20direct%20%3D%20np.zeros((num_output%2C%20num_input))%0A%20%20%20%20delays%20%3D%20np.random.randint(750%2C%202001%2C%20size%3DN)%5BNone%2C%20%3A%5D%0A%0A%20%20%20%20feedback_matrix%20%3D%20random_orthogonal(N)%0A%20%20%20%20return%20N%2C%20delays%2C%20direct%2C%20feedback_matrix%2C%20input_gain%2C%20output_gain%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20Generate%20Absorption%20Ailter%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(N%2C%20delays%2C%20fs%2C%20one_pole_absorption%2C%20pyFDN)%3A%0A%20%20%20%20RT_DC%20%3D%204%20%20%23%20seconds%0A%20%20%20%20RT_NY%20%3D%201%20%20%23%20seconds%0A%0A%20%20%20%20coeffs%20%3D%20one_pole_absorption(RT_DC%2C%20RT_NY%2C%20delays%2C%20fs)%0A%0A%20%20%20%20%23%20Constract%20the%20absorption%0A%20%20%20%20absorption%20%3D%20pyFDN.SOSFilterBank(coeffs%2C%20N)%0A%20%20%20%20return%20(absorption%2C)%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20Time%20Varying%20Matrix%20Generation%20%26%20Reverberation%20Processing%20Across%20Matrix%20Variations%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20N%2C%0A%20%20%20%20TimeVaryingMatrix%2C%0A%20%20%20%20absorption%2C%0A%20%20%20%20delays%2C%0A%20%20%20%20direct%2C%0A%20%20%20%20feedback_matrix%2C%0A%20%20%20%20fs%2C%0A%20%20%20%20input_gain%2C%0A%20%20%20%20output_gain%2C%0A%20%20%20%20process_fdn%2C%0A%20%20%20%20synth%2C%0A)%3A%0A%20%20%20%20matrix_types%20%3D%20%5B%22no_variation%22%2C%20%22slow_variation%22%2C%20%22fast_variation%22%5D%0A%0A%20%20%20%20reverbed_synth%20%3D%20%7B%7D%0A%0A%20%20%20%20for%20matrix_type%20in%20matrix_types%3A%0A%20%20%20%20%20%20%20%20if%20matrix_type%20%3D%3D%20%22no_variation%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20modulation_frequency%20%3D%200%20%20%23%20hz%0A%20%20%20%20%20%20%20%20%20%20%20%20modulation_amplitude%20%3D%200.0%0A%20%20%20%20%20%20%20%20%20%20%20%20spread%20%3D%200%0A%0A%20%20%20%20%20%20%20%20elif%20matrix_type%20%3D%3D%20%22slow_variation%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20modulation_frequency%20%3D%201.0%20%20%23%20hz%0A%20%20%20%20%20%20%20%20%20%20%20%20modulation_amplitude%20%3D%203.0%0A%20%20%20%20%20%20%20%20%20%20%20%20spread%20%3D%200.3%0A%0A%20%20%20%20%20%20%20%20elif%20matrix_type%20%3D%3D%20%22fast_variation%22%3A%0A%20%20%20%20%20%20%20%20%20%20%20%20modulation_frequency%20%3D%2010%20%20%23%20hz%0A%20%20%20%20%20%20%20%20%20%20%20%20modulation_amplitude%20%3D%201.1%0A%20%20%20%20%20%20%20%20%20%20%20%20spread%20%3D%200.7%0A%0A%20%20%20%20%20%20%20%20tv_matrix%20%3D%20TimeVaryingMatrix(%0A%20%20%20%20%20%20%20%20%20%20%20%20N%2C%20modulation_frequency%2C%20modulation_amplitude%2C%20fs%2C%20spread%0A%20%20%20%20%20%20%20%20)%0A%0A%20%20%20%20%20%20%20%20reverbed_synth%5Bmatrix_type%5D%20%3D%20process_fdn(%0A%20%20%20%20%20%20%20%20%20%20%20%20synth%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20delays%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20feedback_matrix%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20input_gain%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20output_gain%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20direct%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20absorption%3Dabsorption%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20extra_matrix%3Dtv_matrix%2C%0A%20%20%20%20%20%20%20%20)%0A%20%20%20%20return%20matrix_types%2C%20reverbed_synth%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20Output%20Visualization%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(fs%2C%20matrix_types%2C%20mo%2C%20pyFDN%2C%20reverbed_synth)%3A%0A%20%20%20%20mo.vstack(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20pyFDN.plot_spectrogram(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20reverbed_synth%5Bname%5D%5B%3A%2C%200%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20fs%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20nperseg%3D2048%20*%208%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20noverlap%3D2048%20*%201%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20title%3Df%22%7Bname%7D%20%E2%80%94%20spectrogram%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20colorscale%3D%22Magma%22%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20height%3D350%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20name%20in%20matrix_types%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0A%40app.cell(hide_code%3DTrue)%0Adef%20_(mo)%3A%0A%20%20%20%20mo.md(r%22%22%22%0A%20%20%20%20%23%23%23%20Audio%20Playback%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(fs%2C%20matrix_types%2C%20mo%2C%20reverbed_synth)%3A%0A%20%20%20%20mo.vstack(%0A%20%20%20%20%20%20%20%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20mo.vstack(%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5Bmo.md(f%22**%7Bname%7D**%22)%2C%20mo.audio(src%3Dreverbed_synth%5Bname%5D.T%2C%20rate%3Dfs)%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20)%0A%20%20%20%20%20%20%20%20%20%20%20%20for%20name%20in%20matrix_types%0A%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20)%0A%20%20%20%20return%0A%0A%0Aif%20__name__%20%3D%3D%20%22__main__%22%3A%0A%20%20%20%20app.run()%0A
60d708bf40267d21948bb3993090a124