%23%20gallery_category%3A%20Allpass%20FDN%20Examples%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%20FDN%20with%20Schroeder%20allpass%20filters%20in%20the%20loop%0A%0A%20%20%20%20Schroeder%20allpass%20filters%20can%20be%20placed%20**behind%20the%20delays**%20in%20the%20FDN%20loop%20to%20increase%20echo%20density.%20The%20rendering%20is%20done%20with%20**FLAMO**%20(gain%20and%20delay%20modules).%0A%0A%20%20%20%20Steps%3A%0A%20%20%20%201.%20Build%20a%20**MIMO%20parallel%20Schroeder%20allpass**%20(block-diagonal).%0A%20%20%20%202.%20Build%20a%20**vanilla%20FDN%20(SISO)**.%0A%20%20%20%203.%20Place%20the%20**Schroeder%20allpass%20behind%20the%20delays**%20of%20the%20FDN%20and%20render.%0A%0A%20%20%20%20%3E%20Reference%3A%20V%C3%A4%C3%A4n%C3%A4nen%2C%20R.%2C%20V%C3%A4lim%C3%A4ki%2C%20V.%2C%20Huopaniemi%2C%20J.%20%26%20Karjalainen%2C%20M.%20Efficient%20and%20Parametric%20Reverberator%20for%20Room%20Acoustics%20Modeling.%20200%E2%80%93203%20(1997).%0A%0A%0A%20%20%20%20%E2%80%94%20Original%20MATLAB%3A%20Sebastian%20J.%20Schlecht%2C%2029%20Dec%202019%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%20%23%23%20Setup%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%20plotly.io%20as%20pio%0A%0A%20%20%20%20pio.renderers.default%20%3D%20%22sphinx_gallery%22%20%20%23%20interactive%20in%20Jupyter%20%2B%20docs%20HTML%0A%0A%20%20%20%20import%20pyFDN%0A%0A%20%20%20%20np.random.seed(6)%0A%20%20%20%20Fs%20%3D%2048000%0A%20%20%20%20nfft%20%3D%202**16%0A%20%20%20%20return%20Fs%2C%20nfft%2C%20np%2C%20pyFDN%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%201.%20MIMO%20parallel%20Schroeder%20allpass%0A%0A%20%20%20%20Build%20N%20parallel%20SISO%20Schroeder%20allpasses%20(block-diagonal%20DSS)%2C%20convert%20to%20FLAMO%20with%20**dss_to_flamo**%2C%20render%20and%20play.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Fs%2C%20nfft%2C%20np%2C%20pyFDN)%3A%0A%20%20%20%20N%20%3D%204%0A%20%20%20%20sections_per%20%3D%202%0A%20%20%20%20gain_per_sample_sch%20%3D%20pyFDN.rt_to_gain_per_sample(0.2%2C%20Fs)%0A%20%20%20%20delays_per%20%3D%20np.random.randint(30%2C%20200%2C%20size%3D(N%2C%20sections_per))%0A%20%20%20%20g_per%20%3D%20gain_per_sample_sch**delays_per%20*%200%20%2B%200.7%0A%0A%20%20%20%20A_list%2C%20B_list%2C%20C_list%2C%20D_list%2C%20delays_list%20%3D%20%5B%5D%2C%20%5B%5D%2C%20%5B%5D%2C%20%5B%5D%2C%20%5B%5D%0A%20%20%20%20for%20i%20in%20range(N)%3A%0A%20%20%20%20%20%20%20%20Ai%2C%20bi%2C%20ci%2C%20di%20%3D%20pyFDN.series_allpass(g_per%5Bi%5D)%0A%20%20%20%20%20%20%20%20A_list.append(Ai)%0A%20%20%20%20%20%20%20%20B_list.append(bi)%0A%20%20%20%20%20%20%20%20C_list.append(ci)%0A%20%20%20%20%20%20%20%20D_list.append(di)%0A%20%20%20%20%20%20%20%20delays_list.append(delays_per%5Bi%5D)%20%20%23%201%20sample%20per%20section%0A%0A%20%20%20%20from%20scipy.linalg%20import%20block_diag%0A%0A%20%20%20%20A_sch%20%3D%20block_diag(*A_list)%0A%20%20%20%20B_sch%20%3D%20block_diag(*B_list)%0A%20%20%20%20C_sch%20%3D%20block_diag(*C_list)%0A%20%20%20%20D_sch%20%3D%20block_diag(*D_list)%0A%20%20%20%20delays_sch%20%3D%20np.concatenate(delays_list)%0A%0A%20%20%20%20model_sch%20%3D%20pyFDN.dss_to_flamo(%0A%20%20%20%20%20%20%20%20A_sch%2C%20B_sch%2C%20C_sch%2C%20D_sch%2C%20delays_sch%2C%20Fs%2C%20nfft%3Dnfft%0A%20%20%20%20)%0A%20%20%20%20ir_sch%20%3D%20pyFDN.flamo_time_response(model_sch)%0A%20%20%20%20return%20A_sch%2C%20B_sch%2C%20C_sch%2C%20D_sch%2C%20N%2C%20delays_sch%2C%20ir_sch%0A%0A%0A%40app.cell%0Adef%20_(A_sch%2C%20B_sch%2C%20C_sch%2C%20D_sch%2C%20delays_sch%2C%20ir_sch%2C%20pyFDN)%3A%0A%20%20%20%20print(ir_sch.shape)%0A%20%20%20%20print(delays_sch)%0A%20%20%20%20pyFDN.plot_system_matrix(A_sch%2C%20B_sch%2C%20C_sch%2C%20D_sch)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Fs%2C%20ir_sch%2C%20mo%2C%20np%2C%20pyFDN)%3A%0A%20%20%20%20ir_sch_channel%20%3D%20ir_sch%5B0%2C%20%3A%2C%201%5D.squeeze()%0A%20%20%20%20_fig%20%3D%20pyFDN.plot_impulse_response(%0A%20%20%20%20%20%20%20%20ir_sch_channel%2C%0A%20%20%20%20%20%20%20%20fs%3DFs%2C%0A%20%20%20%20%20%20%20%20title%3D%22MIMO%20parallel%20Schroeder%20allpass%20%E2%80%94%20impulse%20response%20(in0%E2%86%92out0)%22%2C%0A%20%20%20%20)%0A%0A%20%20%20%20mo.vstack(%5B_fig%2C%20mo.audio(np.asarray(ir_sch_channel)%2C%20Fs)%5D)%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%202.%20Vanilla%20FDN%20(SISO)%0A%0A%20%20%20%20Random%20orthogonal%20feedback%20matrix%2C%20gains%20from%20delays%2C%20B%2FC%2FD%20identity-like.%20Build%20FLAMO%20with%20**dss_to_flamo**%2C%20render%20and%20play.%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(Fs%2C%20N%2C%20nfft%2C%20np%2C%20pyFDN)%3A%0A%20%20%20%20delays_fdn%20%3D%20np.random.randint(1200%2C%207900%2C%20size%3DN)%0A%20%20%20%20feedback_matrix%20%3D%20pyFDN.random_orthogonal(N)%0A%0A%20%20%20%20B_fdn%20%3D%20np.ones((N%2C%201))%0A%20%20%20%20C_fdn%20%3D%20np.ones((1%2C%20N))%0A%20%20%20%20D_fdn%20%3D%20np.ones((1%2C%201))%0A%0A%20%20%20%20rt_dc%20%3D%202.0%0A%20%20%20%20rt_ny%20%3D%200.7%0A%20%20%20%20sos%20%3D%20pyFDN.first_order_absorption(rt_dc%2C%20rt_ny%2C%20delays_fdn%2C%20fs%3DFs)%0A%0A%20%20%20%20model_fdn%20%3D%20pyFDN.dss_to_flamo(%0A%20%20%20%20%20%20%20%20feedback_matrix%2C%20B_fdn%2C%20C_fdn%2C%20D_fdn%2C%20delays_fdn%2C%20Fs%2C%20nfft%3Dnfft%2C%20sos_filter%3Dsos%0A%20%20%20%20)%0A%20%20%20%20ir_fdn%20%3D%20pyFDN.flamo_time_response(model_fdn).squeeze()%0A%20%20%20%20print(ir_fdn.shape)%0A%20%20%20%20print(delays_fdn)%0A%20%20%20%20print(sos.shape)%0A%20%20%20%20return%20B_fdn%2C%20C_fdn%2C%20D_fdn%2C%20delays_fdn%2C%20feedback_matrix%2C%20ir_fdn%2C%20sos%0A%0A%0A%40app.cell%0Adef%20_(Fs%2C%20ir_fdn%2C%20mo%2C%20np%2C%20pyFDN)%3A%0A%20%20%20%20_fig%20%3D%20pyFDN.plot_impulse_response(%0A%20%20%20%20%20%20%20%20ir_fdn%2C%0A%20%20%20%20%20%20%20%20fs%3DFs%2C%0A%20%20%20%20%20%20%20%20title%3D%22Vanilla%20FDN%20(SISO)%20%E2%80%94%20impulse%20response%22%2C%0A%20%20%20%20)%0A%0A%20%20%20%20mo.vstack(%5B_fig%2C%20mo.audio(np.asarray(ir_fdn)%2C%20Fs)%5D)%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%203.%20FDN%20with%20Schroeder%20allpass%20behind%20the%20delays%0A%0A%20%20%20%20Reuse%20the%20two%20models%20above%3A%20take%20the%20**vanilla%20FDN**%20(feedback_matrix%2C%20B_fdn%2C%20C_fdn%2C%20D_fdn%2C%20delays_fdn)%20and%20the%20**MIMO%20Schroeder%20allpass**%20(A_sch%2C%20B_sch%2C%20C_sch%2C%20D_sch%2C%20delays_sch).%20Build%20the%20Schroeder%20as%20a%20core%20with%20**dss_to_flamo(...%2C%20shell%3DFalse)**%20and%20pass%20it%20as%20**post_delay_module**%20to%20append%20it%20to%20the%20FDN's%20forward%20path%20(after%20the%20FDN%20delays).%0A%20%20%20%20%22%22%22)%0A%20%20%20%20return%0A%0A%0A%40app.cell%0Adef%20_(%0A%20%20%20%20A_sch%2C%0A%20%20%20%20B_fdn%2C%0A%20%20%20%20B_sch%2C%0A%20%20%20%20C_fdn%2C%0A%20%20%20%20C_sch%2C%0A%20%20%20%20D_fdn%2C%0A%20%20%20%20D_sch%2C%0A%20%20%20%20Fs%2C%0A%20%20%20%20delays_fdn%2C%0A%20%20%20%20delays_sch%2C%0A%20%20%20%20feedback_matrix%2C%0A%20%20%20%20nfft%2C%0A%20%20%20%20pyFDN%2C%0A%20%20%20%20sos%2C%0A)%3A%0A%20%20%20%20%23%20Schroeder%20core%20(4-in%2C%204-out)%20from%20section%201%3B%20append%20to%20FDN%20forward%20path%0A%20%20%20%20schroeder_core%20%3D%20pyFDN.dss_to_flamo(%0A%20%20%20%20%20%20%20%20A_sch%2C%0A%20%20%20%20%20%20%20%20B_sch%2C%0A%20%20%20%20%20%20%20%20C_sch%2C%0A%20%20%20%20%20%20%20%20D_sch%2C%0A%20%20%20%20%20%20%20%20delays_sch%2C%0A%20%20%20%20%20%20%20%20Fs%2C%0A%20%20%20%20%20%20%20%20nfft%3Dnfft%2C%0A%20%20%20%20%20%20%20%20shell%3DFalse%2C%0A%20%20%20%20)%0A%20%20%20%20model_fdn_ap%20%3D%20pyFDN.dss_to_flamo(%0A%20%20%20%20%20%20%20%20feedback_matrix%2C%0A%20%20%20%20%20%20%20%20B_fdn%2C%0A%20%20%20%20%20%20%20%20C_fdn%2C%0A%20%20%20%20%20%20%20%20D_fdn%2C%0A%20%20%20%20%20%20%20%20delays_fdn%2C%0A%20%20%20%20%20%20%20%20Fs%2C%0A%20%20%20%20%20%20%20%20nfft%3Dnfft%2C%0A%20%20%20%20%20%20%20%20sos_filter%3Dsos%2C%0A%20%20%20%20%20%20%20%20post_delay_module%3Dschroeder_core%2C%0A%20%20%20%20)%0A%20%20%20%20ir_fdn_ap%20%3D%20pyFDN.flamo_time_response(model_fdn_ap).squeeze()%0A%0A%20%20%20%20pyFDN.plot_flamo_graph(model_fdn_ap)%0A%20%20%20%20return%20(ir_fdn_ap%2C)%0A%0A%0A%40app.cell%0Adef%20_(Fs%2C%20ir_fdn_ap%2C%20mo%2C%20np%2C%20pyFDN)%3A%0A%20%20%20%20_fig%20%3D%20pyFDN.plot_impulse_response(%0A%20%20%20%20%20%20%20%20ir_fdn_ap%2C%0A%20%20%20%20%20%20%20%20fs%3DFs%2C%0A%20%20%20%20%20%20%20%20title%3D%22FDN%20with%20Schroeder%20allpass%20behind%20delays%20%E2%80%94%20impulse%20response%22%2C%0A%20%20%20%20)%0A%0A%20%20%20%20mo.vstack(%5B_fig%2C%20mo.audio(np.asarray(ir_fdn_ap)%2C%20Fs)%5D)%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
10dde589387fcb28514cce82cefbeba0