File: pvshell.h

package info (click to toggle)
audacity 2.1.2-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 86,844 kB
  • sloc: ansic: 225,005; cpp: 221,240; sh: 27,327; python: 16,896; makefile: 8,186; lisp: 8,002; perl: 317; xml: 307; sed: 16
file content (92 lines) | stat: -rw-r--r-- 4,198 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/* pvshell.h -- a generic Nyquist primitive, esp. for phase vocoder */

/* how many doubles to provide for miscellaneous state info */
#define PVSHELL_STATE_MAX 8

/* define some bits to return conditions */
#define PVSHELL_FLAG_TERMINATE 4
#define PVSHELL_FLAG_LOGICAL_STOP 8

/* this function is called to compute samples. It should compute n
 * samples (floats == sample_type) and store them at out[i]. 
 * You can return less than n samples by writing the actual number
 * of samples computed into *n. Normally, you return zero.
 * To indicate that the time of the FIRST sample is the logical stop 
 * time, return PVSHELL_FLAG_LOGICAL_STOP. (If the logical stop time
 * is not at the first sample, but instead at sample j, then just
 * return j samples (from 0 to j-1), save the rest of the samples, 
 * and the next time, the first sample will correspond to the logical
 * stop time, so you can return PVSHELL_FLAG_LOGICAL_STOP.
 * To indicate that the sound has terminated, return 
 * PVSHELL_FLAG_TERMINATE. This should be the only time you return
 * zero samples. (As with logical stop time, if you have samples to
 * return before termination, then do it, and return 
 * PVSHELL_FLAG_TERMINATE the next time you are called, at which
 * point you've returned all the samples, so you can set *n = 0.
 */
struct pvshell_struct;

typedef long (*h_fn_type)(struct pvshell_struct *susp, 
                          sample_block_values_type out, long *n);

typedef struct pvshell_struct {
    sound_type f;
    long f_cnt;
    sample_block_values_type f_ptr;

    sound_type g;
    long g_cnt;
    sample_block_values_type g_ptr;

    long flags; /* for terminated and logically stopped flags */

    // state is extra storage for whatever you like
    double state[PVSHELL_STATE_MAX];
    
    // h is a function that computes sound from f, g, x, y, state
    h_fn_type h;
} pvshell_node, *pvshell_type;    


/* to get samples from f or g, use these macros. For each sample, call
 * PVSHELL_TEST_X to get logical stop and terminate flags (but do not
 * fetch a sample). Then, if you want, call PVSHELL_FETCH_X to get the
 * next sample. You can call PVSHELL_TEST_X multiple times before
 * calling PVSHELL_FETCH_X, e.g. you can return exit a loop when you
 * see a logical stop flag and later call PVSHELL_TEST_X again. You
 * CANNOT call PVSHELL_FETCH_X multiples times without an intervening
 * call to PVSHELL_TEST_X. Finally, the logical stop flag is only
 * returned once. Normally you should write something like:
 *    new_flags = PVSHELL_TEST_F(susp);
 *    susp->flags | = new_flags; // remember flags
 *    if (new_flags) break;
 * in the sample loop so that you will break when you see logical_stop.
 * Outside the loop, you can return (*n ? 0 : susp->flags) which will
 * return 0 if you computed samples before the logical stop was detected.
 * Then the next time you are called, you will return the logical_stop
 * flag because you saved it in susp->flags, and the flag applies to the
 * *beginning* of the sample block. This code handles terminate too.
 */
long pvshell_test_f(pvshell_type susp);
long pvshell_test_g(pvshell_type susp);
#define PVSHELL_TEST_F(susp) ((susp)->f_cnt == 0 ? pvshell_test_f(susp) : 0)
#define PVSHELL_FETCH_F(susp) ((susp)->f_cnt--, (*(susp)->f_ptr++))

#define PVSHELL_TEST_G(susp) ((susp)->g_cnt == 0 ? pvshell_test_g(susp) : 0)
#define PVSHELL_FETCH_G(susp) ((susp)->g_cnt--, (*(susp)->g_ptr++))

/* snd_make_pvshell -- create an instance of pvshell.
   name -- string name of the operation, for debugging & printing
           (name is not copied. It must be a permanent, immutable string.)
   sr -- sample rate of output sound
   t0 -- start time of output sound
   h -- function that computes samples of output
   f -- first input sound, e.g. sound to be time-stretched
   g -- second input sound, e.g. sound to control varying stretch factor
   state -- initial state information needed by h
   n -- number of doubles in state (< PVSHELL_STATE_MAX)
*/
sound_type snd_make_pvshell(char *name, rate_type sr, time_type t0,
                            h_fn_type h, sound_type f, sound_type g, 
                            double *state, long n);