1 
2 /*
3  * The Real SoundTracker - Mixer module definitions
4  *
5  * Copyright (C) 1998-2019 Michael Krause
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21 
22 #ifndef _ST_MIXER_H
23 #define _ST_MIXER_H
24 
25 #include <glib.h>
26 
27 typedef struct st_mixer_sample_info {
28     guint32 looptype; /* see ST_MIXER_SAMPLE_LOOPTYPE_ defines below */
29     guint32 length; /* length in samples, not in bytes */
30     guint32 loopstart; /* offset in samples, not in bytes */
31     guint32 loopend; /* offset to first sample not being played */
32     gint16* data; /* pointer to sample data */
33     GMutex lock;
34 } st_mixer_sample_info;
35 
36 /* values for st_mixer_sample_info.looptype */
37 #define ST_MIXER_SAMPLE_LOOPTYPE_NONE 0
38 #define ST_MIXER_SAMPLE_LOOPTYPE_AMIGA 1
39 #define ST_MIXER_SAMPLE_LOOPTYPE_PINGPONG 2
40 
41 typedef struct st_mixer_channel_status {
42     st_mixer_sample_info* current_sample;
43     guint32 current_position;
44 } st_mixer_channel_status;
45 
46 typedef struct st_mixer {
47     const char* id;
48     const char* description;
49 
50     /* set number of channels to be mixed */
51     void (*setnumch)(int numchannels);
52 
53     /* notify sample update (sample must be locked by caller!) */
54     void (*updatesample)(st_mixer_sample_info* si);
55 
56     /* set mixer output format -- signed 16 or 8 (in machine endianness) */
57     gboolean (*setmixformat)(int format);
58 
59     /* toggle stereo mixing -- interleaved left / right samples */
60     gboolean (*setstereo)(int on);
61 
62     /* set mixing frequency */
63     void (*setmixfreq)(guint32 frequency);
64 
65     /* set final amplification factor (0.0 = mute ... 1.0 = normal ... +inf = REAL LOUD! :D)*/
66     void (*setampfactor)(float amplification);
67 
68     /* returns true if last mix() call had to clip the signal */
69     gboolean (*getclipflag)(void);
70 
71     /* reset internal playing state */
72     void (*reset)(void);
73 
74     /* play sample from the beginning, initialize nothing else */
75     void (*startnote)(int channel, st_mixer_sample_info* si);
76 
77     /* stop note */
78     void (*stopnote)(int channel);
79 
80     /* set curent sample play position */
81     void (*setsmplpos)(int channel, guint32 offset);
82 
83     /* set curent sample play end position */
84     void (*setsmplend)(int channel, guint32 offset);
85 
86     /* set replay frequency (Hz) */
87     void (*setfreq)(int channel, float frequency);
88 
89     /* set sample volume (0.0 ... 1.0) */
90     void (*setvolume)(int channel, float volume);
91 
92     /* set sample panning (-1.0 ... +1.0) */
93     void (*setpanning)(int channel, float panning);
94 
95     /* set channel filter cutoff frequency (-1.0 for off, or 0.0 ... +1.0) */
96     void (*setchcutoff)(int channel, float freq);
97 
98     /* set channel filter resonance (0.0 ... +1.0) */
99     void (*setchreso)(int channel, float reso);
100 
101     /* do the mix, return pointer to end of dest */
102     void* (*mix)(void* dest, guint32 count, gint16* scopebufs[], int scopebuf_offset);
103 
104     /* get status information */
105     void (*dumpstatus)(st_mixer_channel_status array[]);
106 
107     /* load channel settings from tracer */
108     void (*loadchsettings)(int channel);
109 
110     guint32 max_sample_length;
111 
112     struct st_mixer* next;
113 } st_mixer;
114 
115 typedef enum {
116     ST_MIXER_FORMAT_S16_LE = 1,
117     ST_MIXER_FORMAT_S16_BE,
118     ST_MIXER_FORMAT_S8,
119     ST_MIXER_FORMAT_U16_LE,
120     ST_MIXER_FORMAT_U16_BE,
121     ST_MIXER_FORMAT_U8,
122     ST_MIXER_FORMAT_STEREO = 16,
123 } STMixerFormat;
124 
125 static const guint res[] = { 1, 2, 2, 1, 2, 2, 1, 1 }; /* In bytes, first and last ones for safety */
126 
127 static inline guint
mixer_get_resolution(STMixerFormat f)128 mixer_get_resolution(STMixerFormat f)
129 {
130     return res[f & 0x7];
131 }
132 
133 static inline guint
mixer_is_format_stereo(STMixerFormat f)134 mixer_is_format_stereo(STMixerFormat f)
135 {
136     return (f & ST_MIXER_FORMAT_STEREO) ? 1 : 0;
137 }
138 
139 #endif /* _MIXER_H */
140