Ejemplo n.º 1
0
def partial_at(p: np.ndarray, t: float, extend=False) -> Opt[np.ndarray]:
    """
    Evaluates partial `p` at time `t`

    Args:
        p: the partial, a 2D numpy array
        t: the time to evaluate the partial at
        extend: should the partial be extended to -inf, +inf? If True, querying a partial
            outside its boundaries will result in the values at the boundaries.
            Otherwise, None is returned

    Returns:
        the breakpoint at t (a np array of shape (4,) with columns (time, freq, amp, bw).
        Returns None if the array is not defined at the given time
    """
    if extend:
        bp = npx.table_interpol_linear(p, np.array([t], dtype=float))
    else:
        t0, t1 = p[0, 0], p[-1, 0]
        if t0 <= t <= t1:
            bp = npx.table_interpol_linear(p, np.array([t], dtype=float))
        else:
            return None
    bp.shape = (4, )
    return bp
Ejemplo n.º 2
0
def partial_at(p, t, extend=False):
    """
    Evaluates partial `p` at time `t`

    p: the partial
    t: the time to evaluate the partial at
    extend: should the partial be extended to -inf, +inf? If True, querying a partial 
        outside its boundaries will result in the values at the boundaries.
        Otherwise, None is returned
    """
    # TODO: implement this as a bisected search on times, interpolate
    if extend:
        bp = npx.table_interpol_linear(p, np.array([t], dtype=float))
    else:
        t0, t1 = p[0, 0], p[-1, 0]
        if t0 <= t <= t1:
            bp = npx.table_interpol_linear(p, np.array([t], dtype=float))
        else:
            return None
    bp.shape = (4, )
    return bp
Ejemplo n.º 3
0
def partial_at(p, t, extend=False):
    """
    Evaluates partial `p` at time `t`

    p: the partial
    t: the time to evaluate the partial at
    extend: should the partial be extended to -inf, +inf? If True, querying a partial 
        outside its boundaries will result in the values at the boundaries.
        Otherwise, None is returned
    """
    # TODO: implement this as a bisected search on times, interpolate
    if extend:
        bp = npx.table_interpol_linear(p, np.array([t], dtype=float))
    else:
        t0, t1 = p[0, 0], p[-1, 0]
        if t0 <= t <= t1:
            bp = npx.table_interpol_linear(p, np.array([t], dtype=float))
        else:
            return None   
    bp.shape = (4,)
    return bp
Ejemplo n.º 4
0
def partial_sample_at(p, times):
    # type: (np.ndarray, t.Union[np.ndarray, list]) -> np.ndarray
    """
    Sample a partial `p` at given times

    p: a partial represented as a 2D-array with columns
       times, freqs, amps, phases, bws

    Returns a partial (2D-array with columns times, freqs, amps, phases, bws)
    """
    times = np.asarray(times, dtype=float)
    data = npx.table_interpol_linear(p, times)
    timescol = times.reshape((times.shape[0], 1))
    return np.hstack((timescol, data))
Ejemplo n.º 5
0
def partial_sample_at(p, times):
    # type: (np.ndarray, t.Union[np.ndarray, list]) -> np.ndarray
    """
    Sample a partial `p` at given times

    p: a partial represented as a 2D-array with columns
       times, freqs, amps, phases, bws

    Returns a partial (2D-array with columns times, freqs, amps, phases, bws)
    """
    times = np.asarray(times, dtype=float)
    data = npx.table_interpol_linear(p, times)
    timescol = times.reshape((times.shape[0], 1))
    return np.hstack((timescol, data))
Ejemplo n.º 6
0
def partial_sample_at(p: np.ndarray, times: np.ndarray) -> np.ndarray:
    """
    Sample a partial `p` at given times

    Args:
        p: a partial represented as a 2D-array with columns
           times, freqs, amps, phases, bws
        times: the times to evaluate partial at

    Returns:
        a partial (2D-array with columns times, freqs, amps, phases, bws)
    """
    assert isinstance(times, np.ndarray)
    t0 = p[0, 0]
    t1 = p[-1, 0]
    index0 = npx.searchsorted1(times, t0)
    index1 = npx.searchsorted1(times, t1) - 1
    times = times[index0:index1]
    data = npx.table_interpol_linear(p, times)
    timescol = times.reshape((times.shape[0], 1))
    return np.hstack((timescol, data))
Ejemplo n.º 7
0
def partials_sample(sp, dt=0.002, t0=-1, t1=-1, maxactive=0, interleave=True):
    # type: (t.List[np.ndarray], float, float, float, int, bool) -> t.Any
    """
    Samples the partials between times `t0` and `t1` with a sampling
    period `dt`. 

    sp: a list of 2D-arrays, each representing a partial
    dt: sampling period
    t0: start time, or None to use the start time of the spectrum
    t1: end time, or None to use the end time of the spectrum
    maxactive: limit the number of active partials to this number. If the 
        number of active streams (partials with non-zero amplitude) if 
        higher than `maxactive`, the softest partials will be zeroed.
        During resynthesis, zeroed partials are skipped. 
        This strategy is followed to allow to pack all partials at the cost
        of having a great amount of streams, and limit the streams (for
        better performance) at the synthesis stage. 
    interleave: if True, all columns of each partial are interleaved
                (see below)

    To be used in connection with `pack`, which packs short non-simultaneous 
    partials into longer ones. The result is a 2D matrix representing the partials.

    Sampling times is calculated as: times = arange(t0, t1+dt, dt)

    * If interleave is True, it returns a big matrix of format

    [[f0, amp0, bw0, f1, amp1, bw1, …, fN, ampN, bwN],   # times[0]
     [f0, amp0, bw0, f1, amp1, bw1, …, fN, ampN, bwN],   # times[1]
     ... 
    ]

    Where (f0, amp0, bw0) represent the freq, amplitude and bandwidth 
    of partial 0 at a given time, (f1, amp1, bw0) the corresponding data 
    for partial 1, etc.

    * If interleave is False, it returns three arrays: freqs, amps, bws
      of the form

    [[f0, f1, f2, ..., fn]  @ times[0]
     [f0, f1, f2, ..., fn]  @ times[1]
    ]
    
    See also
    ~~~~~~~~

    * matrix_save
    * partials_save_matrix

    NB: phase information is not sampled
    """
    if t0 < 0:
        t0 = min(p[0, 0] for p in sp)
    if t1 <= 0:
        t1 = max(p[-1, 0] for p in sp)
    times = np.arange(t0, t1 + dt, dt)
    if not interleave:
        freqs, amps, bws = [], [], []
        for p in sp:
            out = npx.table_interpol_linear(p, times)
            freqs.append(out[:, 0])
            amps.append(out[:, 1])
            bws.append(out[:, 3])
        freqarray = np.column_stack(freqs)
        amparray = np.column_stack(amps)
        bwarray = np.column_stack(bws)
        if maxactive > 0:
            _limit_matrix(amparray, maxactive)
        return freqarray, amparray, bwarray
    else:
        cols = []
        for p in sp:
            p_resampled = npx.table_interpol_linear(p, times)
            # Extract columns: freq, amp, bw (freq is now index 0, because
            # the resampled partial has no times column)
            cols.append(p_resampled[:, (0, 1, 3)])
        m = np.hstack(cols)
        if maxactive > 0:
            _limit_matrix_interleaved(m, maxactive)
        return m
Ejemplo n.º 8
0
def partials_sample(sp, dt=0.002, t0=-1, t1=-1, maxactive=0, interleave=True):
    # type: (t.List[np.ndarray], float, float, float, int, bool) -> t.Any
    """
    Samples the partials between times `t0` and `t1` with a sampling
    period `dt`. 

    sp: a list of 2D-arrays, each representing a partial
    dt: sampling period
    t0: start time, or None to use the start time of the spectrum
    t1: end time, or None to use the end time of the spectrum
    maxactive: limit the number of active partials to this number. If the 
        number of active streams (partials with non-zero amplitude) if 
        higher than `maxactive`, the softest partials will be zeroed.
        During resynthesis, zeroed partials are skipped. 
        This strategy is followed to allow to pack all partials at the cost
        of having a great amount of streams, and limit the streams (for
        better performance) at the synthesis stage. 
    interleave: if True, all columns of each partial are interleaved
                (see below)

    To be used in connection with `pack`, which packs short non-simultaneous 
    partials into longer ones. The result is a 2D matrix representing the partials.

    Sampling times is calculated as: times = arange(t0, t1+dt, dt)

    * If interleave is True, it returns a big matrix of format

    [[f0, amp0, bw0, f1, amp1, bw1, …, fN, ampN, bwN],   # times[0]
     [f0, amp0, bw0, f1, amp1, bw1, …, fN, ampN, bwN],   # times[1]
     ... 
    ]

    Where (f0, amp0, bw0) represent the freq, amplitude and bandwidth 
    of partial 0 at a given time, (f1, amp1, bw0) the corresponding data 
    for partial 1, etc.

    * If interleave is False, it returns three arrays: freqs, amps, bws
      of the form

    [[f0, f1, f2, ..., fn]  @ times[0]
     [f0, f1, f2, ..., fn]  @ times[1]
    ]
    
    See also
    ~~~~~~~~

    * matrix_save
    * partials_save_matrix

    NB: phase information is not sampled
    """
    if t0 < 0:
        t0 = min(p[0, 0] for p in sp)
    if t1 <= 0:
        t1 = max(p[-1, 0] for p in sp)
    times = np.arange(t0, t1+dt, dt)
    if not interleave:
        freqs, amps, bws = [], [], []
        for p in sp:
            out = npx.table_interpol_linear(p, times)
            freqs.append(out[:,0])
            amps.append(out[:,1])
            bws.append(out[:,3])
        freqarray = np.column_stack(freqs)
        amparray = np.column_stack(amps)
        bwarray = np.column_stack(bws)
        if maxactive > 0:
            _limit_matrix(amparray, maxactive)
        return freqarray, amparray, bwarray
    else:
        cols = []
        for p in sp:
            p_resampled = npx.table_interpol_linear(p, times)
            # Extract columns: freq, amp, bw (freq is now index 0, because
            # the resampled partial has no times column)
            cols.append(p_resampled[:,(0, 1, 3)])
        m = np.hstack(cols)
        if maxactive > 0:
            _limit_matrix_interleaved(m, maxactive)
        return m