File: fluidsynth_process.c

package info (click to toggle)
fluidsynth 2.5.2%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 7,268 kB
  • sloc: ansic: 45,303; cpp: 4,897; xml: 864; sh: 200; makefile: 74
file content (117 lines) | stat: -rw-r--r-- 4,158 bytes parent folder | download | duplicates (3)
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
 * This is a C99 program that outlines different usage examples for fluid_synth_process()
 */

#include <stdio.h>
#include <string.h>
#include <fluidsynth.h>

int main()
{
    // any arbitrary number of audio samples to render during on call of fluid_synth_process()
    enum { SAMPLES = 512 };

    // ...creation of synth omitted...

    // USECASE1: render all dry audio channels + reverb and chorus to one stereo channel
    {
        // planar sample buffers that received synthesized (monophonic) audio
        float left[SAMPLES], right[SAMPLES];

        // array of buffers used to setup channel mapping
        float *dry[1 * 2], *fx[1 * 2];

        // first make sure to zero out the sample buffers every time before calling fluid_synth_process()
        memset(left, 0, sizeof(left));
        memset(right, 0, sizeof(right));

        // setup channel mapping for a single stereo channel to which to render all dry audio to
        dry[0] = left;
        dry[1] = right;

        // Setup channel mapping for a single stereo channel to which to render effects to.
        // Just using the same sample buffers as for dry audio is fine here, as it will cause the effects to be mixed with dry output.
        // Note: reverb and chorus together make up two stereo channels. Setting up only one stereo channel is sufficient
        // as the channels wraps around (i.e. chorus will be mixed with reverb channel).
        fx[0] = left;
        fx[1] = right;

        int err = fluid_synth_process(synth, SAMPLES, 2, fx, 2, dry);

        if(err == FLUID_FAILED)
        {
            puts("oops");
        }


        // USECASE2: only render dry audio and discard effects
        // same as above, but call fluid_synth_process() like:
        int err = fluid_synth_process(synth, SAMPLES, 0, NULL, 2, dry);

        if(err == FLUID_FAILED)
        {
            puts("oops");
        }
    }


    // USECASE3: render audio and discard all samples
    {
        int err = fluid_synth_process(synth, SAMPLES, 0, NULL, 0, NULL);

        if(err == FLUID_FAILED)
        {
            puts("oops");
        }
    }


    // USECASE4: multi-channel rendering, i.e. render all audio and effects channels to dedicated audio buffers
    // ofc it‘s not a good idea to allocate all the arrays on the stack
    {
        // lookup number of audio and effect (stereo-)channels of the synth
        // see "synth.audio-channels", "synth.effects-channels" and "synth.effects-groups" settings respectively
        int n_aud_chan = fluid_synth_count_audio_channels(synth);
        
        // by default there are two effects stereo channels (reverb and chorus) ...
        int n_fx_chan = fluid_synth_count_effects_channels(synth);
        
        // ... for each effects unit. Each unit takes care of the effects of one MIDI channel.
        // If there are less units than channels, it wraps around and one unit may render effects of multiple
        // MIDI channels.
        n_fx_chan *= fluid_synth_count_effects_groups();

        // for simplicity, allocate one single sample pool
        float samp_buf[SAMPLES * (n_aud_chan + n_fx_chan) * 2];

        // array of buffers used to setup channel mapping
        float *dry[n_aud_chan * 2], *fx[n_fx_chan * 2];

        // setup buffers to mix dry stereo audio to
        // buffers are alternating left and right for each n_aud_chan,
        // please review documentation of fluid_synth_process()
        for(int i = 0; i < n_aud_chan * 2; i++)
        {
            dry[i] = &samp_buf[i * SAMPLES];
        }

        // setup buffers to mix effects stereo audio to
        // similar channel layout as above, revie fluid_synth_process()
        for(int i = 0; i < n_fx_chan * 2; i++)
        {
            fx[i] = &samp_buf[n_aud_chan * 2 * SAMPLES + i * SAMPLES];
        }

        // dont forget to zero sample buffer(s) before each rendering
        memset(samp_buf, 0, sizeof(samp_buf));

        int err = fluid_synth_process(synth, SAMPLES, n_fx_chan * 2, fx, n_aud_chan * 2, dry);

        if(err == FLUID_FAILED)
        {
            puts("oops");
        }
    }

    return 0;
}