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