def getnl_ir(sweep_generator,output_sweep,branches=5):
    sweep_length = sweep_generator.GetLength()
    sweep_start_freq = sweep_generator.GetStartFrequency()
    sweep_stop_freq = sweep_generator.GetStopFrequency()
    ip_signal = sweep_generator.GetOutput()

    # output_sweep = nlsp.append_zeros(output_sweep)
    rev = sweep_generator.GetReversedOutput()
    rev_spec = sumpf.modules.FourierTransform(rev).GetSpectrum()
    out_spec = sumpf.modules.FourierTransform(output_sweep).GetSpectrum()
    out_spec = out_spec / output_sweep.GetSamplingRate()
    tf = rev_spec * out_spec
    ir_sweep = sumpf.modules.InverseFourierTransform(tf).GetSignal()
    # nlsp.common.plots.plot(ir_sweep)

    ir_sweep_direct = sumpf.modules.CutSignal(signal=ir_sweep,start=0,stop=int(sweep_length/4)).GetOutput()
    ir_sweep_direct = nlsp.append_zeros(ir_sweep_direct)
    ir_merger = sumpf.modules.MergeSignals(on_length_conflict=sumpf.modules.MergeSignals.FILL_WITH_ZEROS)
    ir_merger.AddInput(ir_sweep_direct)
    for i in range(branches-1):
        split_harm = nlsp.FindHarmonicImpulseResponse_Novak(impulse_response=ir_sweep,
                                                            harmonic_order=i+2,
                                                            sweep_generator=sweep_generator).GetHarmonicImpulseResponse()
        split_harm = sumpf.modules.CutSignal(signal=split_harm,stop=len(sweep_generator.GetOutput())).GetOutput()
        ir_merger.AddInput(sumpf.Signal(channels=split_harm.GetChannels(),
                                        samplingrate=ir_sweep.GetSamplingRate(), labels=split_harm.GetLabels()))
    ir_merger = ir_merger.GetOutput()

    # nlsp.common.plots.plot(ir_merger)
    return ir_sweep
def get_nl_harmonics_iden(sweep_generator, response, harmonics):
    sweep_length = sweep_generator.GetLength()
    rev = sweep_generator.GetReversedOutput()
    rev_spec = sumpf.modules.FourierTransform(rev).GetSpectrum()
    out_spec = sumpf.modules.FourierTransform(response).GetSpectrum()
    out_spec = out_spec / response.GetSamplingRate()
    tf = rev_spec * out_spec
    ir_sweep = sumpf.modules.InverseFourierTransform(tf).GetSignal()
    ir_sweep_direct = sumpf.modules.CutSignal(signal=ir_sweep,
                                              start=0,
                                              stop=int(sweep_length /
                                                       4)).GetOutput()
    ir_sweep_direct = nlsp.append_zeros(ir_sweep_direct)
    ir_sweep_direct = nlsp.relabel(ir_sweep_direct, "Identified Harmonics 1")
    ir_merger = sumpf.modules.MergeSignals(
        on_length_conflict=sumpf.modules.MergeSignals.FILL_WITH_ZEROS)
    ir_merger.AddInput(ir_sweep_direct)
    for i in range(harmonics - 1):
        split_harm = nlsp.FindHarmonicImpulseResponse_Novak(
            impulse_response=ir_sweep,
            harmonic_order=i + 2,
            sweep_generator=sweep_generator).GetHarmonicImpulseResponse()
        split_harm = sumpf.modules.CutSignal(
            signal=split_harm,
            stop=len(sweep_generator.GetOutput())).GetOutput()
        ir_merger.AddInput(
            sumpf.Signal(channels=split_harm.GetChannels(),
                         samplingrate=ir_sweep.GetSamplingRate(),
                         labels=("Identified Harmonics %r" % (i + 2), )))
    tf = sumpf.modules.FourierTransform(ir_merger.GetOutput()).GetSpectrum()
    return tf
def change_length_signal(signal, length=None):
    if length is None:
        length = len(signal)
    if len(signal) >= length:
        signal = sumpf.modules.CutSignal(signal=signal, start=0,
                                         stop=length).GetOutput()
    else:
        signal = nlsp.append_zeros(signal, length)
    return signal
def change_length_filterkernels(filter_kernels, length=2**10):
    filter_kernels_modified = []
    for filter in filter_kernels:
        if len(filter) > length:
            filter_kernels_modified.append(
                sumpf.modules.CutSignal(signal=filter, start=0,
                                        stop=length).GetOutput())
        else:
            filter_kernels_modified.append(nlsp.append_zeros(filter, length))
    return filter_kernels_modified
def get_sweep_harmonics_ir(sweep_generator, response, max_harm=None):
    """
    Calculate the harmonics of the sweep based on nonconvolution
    :param excitation: the excitation sweep of the system
    :param response: the response of the system
    :param sweep_start_freq: start frequency of the sweep signal
    :param sweep_stop_freq: stop frequency of the sweep signal
    :param max_harm: the maximum harmonics upto which the harmomics should be calculated
    :return: the sumpf signal of merged harmonic spectrums
    """
    sweep_length = sweep_generator.GetLength()
    excitation = sweep_generator.GetOutput()
    sweep_start_freq = sweep_generator.GetStartFrequency()
    sweep_stop_freq = sweep_generator.GetStopFrequency()
    if sweep_length is None:
        sweep_length = len(excitation)
    if max_harm is None:
        max_harm = 5
    impulse_response = get_impulse_response(excitation, response,
                                            sweep_start_freq, sweep_stop_freq)
    linear = sumpf.modules.CutSignal(signal=impulse_response,
                                     start=0,
                                     stop=len(impulse_response) /
                                     4).GetOutput()
    linear = nlsp.relabel(nlsp.append_zeros(linear), "1 hamonic")
    merger = sumpf.modules.MergeSignals(
        on_length_conflict=sumpf.modules.MergeSignals.FILL_WITH_ZEROS)
    merger.AddInput(linear)
    for i in range(2, max_harm + 1):
        harmonics = sumpf.modules.FindHarmonicImpulseResponse(
            impulse_response=impulse_response,
            harmonic_order=i,
            sweep_start_frequency=sweep_start_freq,
            sweep_stop_frequency=sweep_stop_freq,
            sweep_duration=(
                sweep_length /
                excitation.GetSamplingRate())).GetHarmonicImpulseResponse()
        harmonics = nlsp.relabel(harmonics, "%d harmonic" % i)
        merger.AddInput(
            sumpf.Signal(channels=harmonics.GetChannels(),
                         samplingrate=excitation.GetSamplingRate(),
                         labels=harmonics.GetLabels()))
    harmonics_ir = merger.GetOutput()
    return harmonics_ir
예제 #6
0
def loudspeaker_model_sweep(Plot=True):
    sampling_rate = 48000.0
    start_freq = 100.0
    stop_freq = 20000.0
    length = 2**18
    fade_out = 0.00
    fade_in = 0.00
    branches = 3

    sine = nlsp.NovakSweepGenerator_Cosine(sampling_rate=sampling_rate,
                                           length=length,
                                           start_frequency=start_freq,
                                           stop_frequency=stop_freq,
                                           fade_out=fade_out,
                                           fade_in=fade_in)

    op_sine = sumpf.modules.SignalFile(
        filename="C:/Users/diplomand.8/Desktop/nl_recordings/rec_4_ls/sine.npz",
        format=sumpf.modules.SignalFile.WAV_FLOAT)
    op_sine = sumpf.modules.SplitSignal(data=op_sine.GetSignal(),
                                        channels=[1]).GetOutput()

    found_filter_spec, nl_functions = nlsp.nonlinearconvolution_chebyshev_adaptive(
        sine, op_sine, branches)
    iden_nlsystem_sine = nlsp.HammersteinGroupModel_up(
        input_signal=sine.GetOutput(),
        nonlinear_functions=nl_functions,
        filter_irs=found_filter_spec,
        max_harmonics=range(1, branches + 1))
    linear_op = nlsp.linear_identification_temporalreversal(
        sine, op_sine, sine.GetOutput())
    if Plot is True:
        plot.relabelandplot(
            sumpf.modules.FourierTransform(op_sine).GetSpectrum(),
            "Reference System",
            show=False,
            line='b-')
        plot.relabelandplot(sumpf.modules.FourierTransform(
            iden_nlsystem_sine.GetOutput()).GetSpectrum(),
                            "NL Identified System",
                            show=False,
                            line='r-')
        plot.relabelandplot(
            sumpf.modules.FourierTransform(linear_op).GetSpectrum(),
            "Linear Identified System",
            show=True,
            line='g-')
    print "SNR between Reference and Identified output, nonlinear: %r" % nlsp.snr(
        op_sine, iden_nlsystem_sine.GetOutput())
    print "SNR between Reference and Identified output, linear: %r" % nlsp.snr(
        op_sine, linear_op)

    load_sample = sumpf.modules.SignalFile(
        filename=
        "C:/Users/diplomand.8/Desktop/nl_recordings/rec_4_ls/Speech1.npz",
        format=sumpf.modules.SignalFile.WAV_FLOAT)
    load_sample = nlsp.append_zeros(load_sample.GetSignal())

    ref_sample = sumpf.modules.SplitSignal(data=load_sample,
                                           channels=[1]).GetOutput()
    ip_sample = sumpf.modules.SplitSignal(data=load_sample,
                                          channels=[0]).GetOutput()

    iden_nlsystem_sine.SetInput(ip_sample)
    linear_op = nlsp.linear_identification_temporalreversal(
        sine, op_sine, ip_sample)

    # save the output to the directory
    iden = sumpf.modules.SignalFile(
        filename=
        "C:/Users/diplomand.8/Desktop/nl_recordings/rec_4_ls/sim/identified",
        signal=iden_nlsystem_sine.GetOutput(),
        format=sumpf.modules.SignalFile.WAV_FLOAT)
    ref = sumpf.modules.SignalFile(
        filename=
        "C:/Users/diplomand.8/Desktop/nl_recordings/rec_4_ls/sim/reference",
        signal=ref_sample,
        format=sumpf.modules.SignalFile.WAV_FLOAT)
    inp = sumpf.modules.SignalFile(
        filename=
        "C:/Users/diplomand.8/Desktop/nl_recordings/rec_4_ls/sim/input",
        signal=ip_sample,
        format=sumpf.modules.SignalFile.WAV_FLOAT)
    linear = sumpf.modules.SignalFile(
        filename=
        "C:/Users/diplomand.8/Desktop/nl_recordings/rec_4_ls/sim/linear",
        signal=linear_op,
        format=sumpf.modules.SignalFile.WAV_FLOAT)
    print "Distortion box, SNR between Reference and Identified output Sample,nl: %r" % nlsp.snr(
        ref_sample, iden_nlsystem_sine.GetOutput())
    print "Distortion box, SNR between Reference and Identified output Sample,l: %r" % nlsp.snr(
        ref_sample, linear_op)
def sine_sweepbased_spectralinversion(sweep_generator,
                                      output_sweep,
                                      branches=5):
    """
    Sweep-based system identification using spectral inversion technique and using sine sweep signal.
    :param sweep_generator: the sweep generator object
    :param output_sweep: the output sweep of the nonlinear system
    :param branches: the total number of output branches
    :return: the parameters of HGM (filter kernels and nonlinear functions)
    """
    sweep_length = sweep_generator.GetLength()
    sweep_start_freq = sweep_generator.GetStartFrequency()
    sweep_stop_freq = sweep_generator.GetStopFrequency()
    input_sweep = sweep_generator.GetOutput()

    if isinstance(input_sweep, (sumpf.Signal)):
        ip_signal = input_sweep
        ip_spectrum = sumpf.modules.FourierTransform(
            signal=input_sweep).GetSpectrum()
    else:
        ip_signal = sumpf.modules.InverseFourierTransform(
            spectrum=input_sweep).GetSignal()
        ip_spectrum = input_sweep
    if isinstance(output_sweep, (sumpf.Signal)):
        op_spectrum = sumpf.modules.FourierTransform(
            signal=output_sweep).GetSpectrum()
    else:
        op_spectrum = output_sweep
    inversed_ip = sumpf.modules.RegularizedSpectrumInversion(
        spectrum=ip_spectrum,
        start_frequency=sweep_start_freq + 50,
        stop_frequency=sweep_stop_freq - 100).GetOutput()
    tf_sweep = sumpf.modules.MultiplySpectrums(
        spectrum1=inversed_ip, spectrum2=op_spectrum).GetOutput()
    ir_sweep = sumpf.modules.InverseFourierTransform(
        spectrum=tf_sweep).GetSignal()
    # nlsp.common.plots.plot(ir_sweep)
    ir_sweep_direct = sumpf.modules.CutSignal(signal=ir_sweep,
                                              start=0,
                                              stop=int(sweep_length /
                                                       4)).GetOutput()
    ir_sweep_direct = nlsp.append_zeros(ir_sweep_direct)
    ir_merger = sumpf.modules.MergeSignals(
        on_length_conflict=sumpf.modules.MergeSignals.FILL_WITH_ZEROS)
    ir_merger.AddInput(ir_sweep_direct)
    for i in range(branches - 1):
        split_harm = nlsp.FindHarmonicImpulseResponse_Novak(
            impulse_response=ir_sweep,
            harmonic_order=i + 2,
            sweep_generator=sweep_generator).GetHarmonicImpulseResponse()
        ir_merger.AddInput(
            sumpf.Signal(channels=split_harm.GetChannels(),
                         samplingrate=ir_sweep.GetSamplingRate(),
                         labels=split_harm.GetLabels()))
    ir_merger = ir_merger.GetOutput()

    tf_harmonics_all = sumpf.modules.FourierTransform(
        signal=ir_merger).GetSpectrum()
    harmonics_tf = []
    for i in range(len(tf_harmonics_all.GetChannels())):
        tf_harmonics = sumpf.modules.SplitSpectrum(data=tf_harmonics_all,
                                                   channels=[i]).GetOutput()
        harmonics_tf.append(tf_harmonics)
    A_matrix = numpy.zeros((branches, branches), dtype=numpy.complex128)
    for n in range(0, branches):
        for m in range(0, branches):
            if ((n >= m) and ((n + m) % 2 == 0)):
                A_matrix[m][n] = (((-1 + 0j)**(2 * (n + 1) - m / 2)) /
                                  (2**n)) * nlsp.binomial((n + 1), (n - m) / 2)
            else:
                A_matrix[m][n] = 0
    A_inverse = numpy.linalg.inv(A_matrix)
    for row in range(0, len(A_inverse)):
        if row % 2 != 0.0:
            A_inverse[row] = A_inverse[row] * (0 + 1j)
    B = []
    for row in range(0, branches):
        A = sumpf.modules.ConstantSpectrumGenerator(
            value=0.0,
            resolution=harmonics_tf[0].GetResolution(),
            length=len(harmonics_tf[0])).GetSpectrum()
        for column in range(0, branches):
            temp = sumpf.modules.AmplifySpectrum(
                input=harmonics_tf[column],
                factor=A_inverse[row][column]).GetOutput()
            A = A + temp
        B_temp = nlsp.relabel(
            sumpf.modules.InverseFourierTransform(A).GetSignal(),
            "%r harmonic identified psi" % str(row + 1))
        B.append(B_temp)
    nl_func = nlsp.nl_branches(nlsp.function_factory.power_series, branches)
    return B, nl_func