xref: /OK3568_Linux_fs/kernel/include/sound/wavefront.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun #ifndef __SOUND_WAVEFRONT_H__
3*4882a593Smuzhiyun #define __SOUND_WAVEFRONT_H__
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun /*
6*4882a593Smuzhiyun  *  Driver for Turtle Beach Wavefront cards (Maui,Tropez,Tropez+)
7*4882a593Smuzhiyun  *
8*4882a593Smuzhiyun  *  Copyright (c) by Paul Barton-Davis <pbd@op.net>
9*4882a593Smuzhiyun  */
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #if (!defined(__GNUC__) && !defined(__GNUG__))
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun      You will not be able to compile this file correctly without gcc, because
14*4882a593Smuzhiyun      it is necessary to pack the "wavefront_alias" structure to a size
15*4882a593Smuzhiyun      of 22 bytes, corresponding to 16-bit alignment (as would have been
16*4882a593Smuzhiyun      the case on the original platform, MS-DOS). If this is not done,
17*4882a593Smuzhiyun      then WavePatch-format files cannot be read/written correctly.
18*4882a593Smuzhiyun      The method used to do this here ("__attribute__((packed)") is
19*4882a593Smuzhiyun      completely compiler dependent.
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun      All other wavefront_* types end up aligned to 32 bit values and
22*4882a593Smuzhiyun      still have the same (correct) size.
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun #else
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun      /* However, note that as of G++ 2.7.3.2, g++ was unable to
27*4882a593Smuzhiyun 	correctly parse *type* __attribute__ tags. It will do the
28*4882a593Smuzhiyun 	right thing if we use the "packed" attribute on each struct
29*4882a593Smuzhiyun 	member, which has the same semantics anyway.
30*4882a593Smuzhiyun      */
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun #endif /* __GNUC__ */
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun /***************************** WARNING ********************************
35*4882a593Smuzhiyun   PLEASE DO NOT MODIFY THIS FILE IN ANY WAY THAT AFFECTS ITS ABILITY TO
36*4882a593Smuzhiyun   BE USED WITH EITHER C *OR* C++.
37*4882a593Smuzhiyun  **********************************************************************/
38*4882a593Smuzhiyun 
39*4882a593Smuzhiyun #ifndef NUM_MIDIKEYS
40*4882a593Smuzhiyun #define NUM_MIDIKEYS 128
41*4882a593Smuzhiyun #endif  /* NUM_MIDIKEYS */
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun #ifndef NUM_MIDICHANNELS
44*4882a593Smuzhiyun #define NUM_MIDICHANNELS 16
45*4882a593Smuzhiyun #endif  /* NUM_MIDICHANNELS */
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun /* These are very useful/important. the original wavefront interface
48*4882a593Smuzhiyun    was developed on a 16 bit system, where sizeof(int) = 2
49*4882a593Smuzhiyun    bytes. Defining things like this makes the code much more portable, and
50*4882a593Smuzhiyun    easier to understand without having to toggle back and forth
51*4882a593Smuzhiyun    between a 16-bit view of the world and a 32-bit one.
52*4882a593Smuzhiyun  */
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun #ifndef __KERNEL__
55*4882a593Smuzhiyun /* keep them for compatibility */
56*4882a593Smuzhiyun typedef short s16;
57*4882a593Smuzhiyun typedef unsigned short u16;
58*4882a593Smuzhiyun typedef int s32;
59*4882a593Smuzhiyun typedef unsigned int u32;
60*4882a593Smuzhiyun typedef char s8;
61*4882a593Smuzhiyun typedef unsigned char u8;
62*4882a593Smuzhiyun typedef s16 INT16;
63*4882a593Smuzhiyun typedef u16 UINT16;
64*4882a593Smuzhiyun typedef s32 INT32;
65*4882a593Smuzhiyun typedef u32 UINT32;
66*4882a593Smuzhiyun typedef s8 CHAR8;
67*4882a593Smuzhiyun typedef u8 UCHAR8;
68*4882a593Smuzhiyun #endif
69*4882a593Smuzhiyun 
70*4882a593Smuzhiyun /* Pseudo-commands not part of the WaveFront command set.
71*4882a593Smuzhiyun    These are used for various driver controls and direct
72*4882a593Smuzhiyun    hardware control.
73*4882a593Smuzhiyun  */
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun #define WFC_DEBUG_DRIVER                0
76*4882a593Smuzhiyun #define WFC_FX_IOCTL                    1
77*4882a593Smuzhiyun #define WFC_PATCH_STATUS                2
78*4882a593Smuzhiyun #define WFC_PROGRAM_STATUS              3
79*4882a593Smuzhiyun #define WFC_SAMPLE_STATUS               4
80*4882a593Smuzhiyun #define WFC_DISABLE_INTERRUPTS          5
81*4882a593Smuzhiyun #define WFC_ENABLE_INTERRUPTS           6
82*4882a593Smuzhiyun #define WFC_INTERRUPT_STATUS            7
83*4882a593Smuzhiyun #define WFC_ROMSAMPLES_RDONLY           8
84*4882a593Smuzhiyun #define WFC_IDENTIFY_SLOT_TYPE          9
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun /* Wavefront synth commands
87*4882a593Smuzhiyun  */
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun #define WFC_DOWNLOAD_SAMPLE		0x80
90*4882a593Smuzhiyun #define WFC_DOWNLOAD_BLOCK		0x81
91*4882a593Smuzhiyun #define WFC_DOWNLOAD_MULTISAMPLE	0x82
92*4882a593Smuzhiyun #define WFC_DOWNLOAD_SAMPLE_ALIAS	0x83
93*4882a593Smuzhiyun #define WFC_DELETE_SAMPLE		0x84
94*4882a593Smuzhiyun #define WFC_REPORT_FREE_MEMORY		0x85
95*4882a593Smuzhiyun #define WFC_DOWNLOAD_PATCH		0x86
96*4882a593Smuzhiyun #define WFC_DOWNLOAD_PROGRAM		0x87
97*4882a593Smuzhiyun #define WFC_SET_SYNTHVOL		0x89
98*4882a593Smuzhiyun #define WFC_SET_NVOICES			0x8B
99*4882a593Smuzhiyun #define WFC_DOWNLOAD_DRUM		0x90
100*4882a593Smuzhiyun #define WFC_GET_SYNTHVOL		0x92
101*4882a593Smuzhiyun #define WFC_GET_NVOICES			0x94
102*4882a593Smuzhiyun #define WFC_DISABLE_CHANNEL		0x9A
103*4882a593Smuzhiyun #define WFC_ENABLE_CHANNEL		0x9B
104*4882a593Smuzhiyun #define WFC_MISYNTH_OFF			0x9D
105*4882a593Smuzhiyun #define WFC_MISYNTH_ON			0x9E
106*4882a593Smuzhiyun #define WFC_FIRMWARE_VERSION		0x9F
107*4882a593Smuzhiyun #define WFC_GET_NSAMPLES		0xA0
108*4882a593Smuzhiyun #define WFC_DISABLE_DRUM_PROGRAM	0xA2
109*4882a593Smuzhiyun #define WFC_UPLOAD_PATCH		0xA3
110*4882a593Smuzhiyun #define WFC_UPLOAD_PROGRAM		0xA4
111*4882a593Smuzhiyun #define WFC_SET_TUNING			0xA6
112*4882a593Smuzhiyun #define WFC_GET_TUNING			0xA7
113*4882a593Smuzhiyun #define WFC_VMIDI_ON			0xA8
114*4882a593Smuzhiyun #define WFC_VMIDI_OFF			0xA9
115*4882a593Smuzhiyun #define WFC_MIDI_STATUS			0xAA
116*4882a593Smuzhiyun #define WFC_GET_CHANNEL_STATUS		0xAB
117*4882a593Smuzhiyun #define WFC_DOWNLOAD_SAMPLE_HEADER	0xAC
118*4882a593Smuzhiyun #define WFC_UPLOAD_SAMPLE_HEADER	0xAD
119*4882a593Smuzhiyun #define WFC_UPLOAD_MULTISAMPLE		0xAE
120*4882a593Smuzhiyun #define WFC_UPLOAD_SAMPLE_ALIAS		0xAF
121*4882a593Smuzhiyun #define WFC_IDENTIFY_SAMPLE_TYPE	0xB0
122*4882a593Smuzhiyun #define WFC_DOWNLOAD_EDRUM_PROGRAM	0xB1
123*4882a593Smuzhiyun #define WFC_UPLOAD_EDRUM_PROGRAM	0xB2
124*4882a593Smuzhiyun #define WFC_SET_EDRUM_CHANNEL		0xB3
125*4882a593Smuzhiyun #define WFC_INSTOUT_LEVELS		0xB4
126*4882a593Smuzhiyun #define WFC_PEAKOUT_LEVELS		0xB5
127*4882a593Smuzhiyun #define WFC_REPORT_CHANNEL_PROGRAMS	0xB6
128*4882a593Smuzhiyun #define WFC_HARDWARE_VERSION		0xCF
129*4882a593Smuzhiyun #define WFC_UPLOAD_SAMPLE_PARAMS	0xD7
130*4882a593Smuzhiyun #define WFC_DOWNLOAD_OS			0xF1
131*4882a593Smuzhiyun #define WFC_NOOP                        0xFF
132*4882a593Smuzhiyun 
133*4882a593Smuzhiyun #define WF_MAX_SAMPLE   512
134*4882a593Smuzhiyun #define WF_MAX_PATCH    256
135*4882a593Smuzhiyun #define WF_MAX_PROGRAM  128
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun #define WF_SECTION_MAX  44   /* longest OS section length */
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun /* # of bytes we send to the board when sending it various kinds of
140*4882a593Smuzhiyun    substantive data, such as samples, patches and programs.
141*4882a593Smuzhiyun */
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun #define WF_PROGRAM_BYTES 32
144*4882a593Smuzhiyun #define WF_PATCH_BYTES 132
145*4882a593Smuzhiyun #define WF_SAMPLE_BYTES 27
146*4882a593Smuzhiyun #define WF_SAMPLE_HDR_BYTES 25
147*4882a593Smuzhiyun #define WF_ALIAS_BYTES 25
148*4882a593Smuzhiyun #define WF_DRUM_BYTES 9
149*4882a593Smuzhiyun #define WF_MSAMPLE_BYTES 259 /* (MIDI_KEYS * 2) + 3 */
150*4882a593Smuzhiyun 
151*4882a593Smuzhiyun #define WF_ACK     0x80
152*4882a593Smuzhiyun #define WF_DMA_ACK 0x81
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun /* OR-values for MIDI status bits */
155*4882a593Smuzhiyun 
156*4882a593Smuzhiyun #define WF_MIDI_VIRTUAL_ENABLED 0x1
157*4882a593Smuzhiyun #define WF_MIDI_VIRTUAL_IS_EXTERNAL 0x2
158*4882a593Smuzhiyun #define WF_MIDI_IN_TO_SYNTH_DISABLED 0x4
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun /* slot indexes for struct address_info: makes code a little more mnemonic */
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun #define WF_SYNTH_SLOT         0
163*4882a593Smuzhiyun #define WF_INTERNAL_MIDI_SLOT 1
164*4882a593Smuzhiyun #define WF_EXTERNAL_MIDI_SLOT 2
165*4882a593Smuzhiyun 
166*4882a593Smuzhiyun /* Magic MIDI bytes used to switch I/O streams on the ICS2115 MPU401
167*4882a593Smuzhiyun    emulation. Note these NEVER show up in output from the device and
168*4882a593Smuzhiyun    should NEVER be used in input unless Virtual MIDI mode has been
169*4882a593Smuzhiyun    disabled. If they do show up as input, the results are unpredictable.
170*4882a593Smuzhiyun */
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun #define WF_EXTERNAL_SWITCH  0xFD
173*4882a593Smuzhiyun #define WF_INTERNAL_SWITCH  0xF9
174*4882a593Smuzhiyun 
175*4882a593Smuzhiyun /* Debugging flags */
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun #define WF_DEBUG_CMD 0x1
178*4882a593Smuzhiyun #define WF_DEBUG_DATA 0x2
179*4882a593Smuzhiyun #define WF_DEBUG_LOAD_PATCH 0x4
180*4882a593Smuzhiyun #define WF_DEBUG_IO 0x8
181*4882a593Smuzhiyun 
182*4882a593Smuzhiyun /* WavePatch file format stuff */
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun #define WF_WAVEPATCH_VERSION     120;  /*  Current version number (1.2)  */
185*4882a593Smuzhiyun #define WF_MAX_COMMENT           64    /*  Comment length */
186*4882a593Smuzhiyun #define WF_NUM_LAYERS            4
187*4882a593Smuzhiyun #define WF_NAME_LENGTH           32
188*4882a593Smuzhiyun #define WF_SOURCE_LENGTH         260
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun #define BankFileID     "Bank"
191*4882a593Smuzhiyun #define DrumkitFileID  "DrumKit"
192*4882a593Smuzhiyun #define ProgramFileID  "Program"
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun struct wf_envelope
195*4882a593Smuzhiyun {
196*4882a593Smuzhiyun     u8 attack_time:7;
197*4882a593Smuzhiyun     u8 Unused1:1;
198*4882a593Smuzhiyun 
199*4882a593Smuzhiyun     u8 decay1_time:7;
200*4882a593Smuzhiyun     u8 Unused2:1;
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun     u8 decay2_time:7;
203*4882a593Smuzhiyun     u8 Unused3:1;
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun     u8 sustain_time:7;
206*4882a593Smuzhiyun     u8 Unused4:1;
207*4882a593Smuzhiyun 
208*4882a593Smuzhiyun     u8 release_time:7;
209*4882a593Smuzhiyun     u8 Unused5:1;
210*4882a593Smuzhiyun 
211*4882a593Smuzhiyun     u8 release2_time:7;
212*4882a593Smuzhiyun     u8 Unused6:1;
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun     s8 attack_level;
215*4882a593Smuzhiyun     s8 decay1_level;
216*4882a593Smuzhiyun     s8 decay2_level;
217*4882a593Smuzhiyun     s8 sustain_level;
218*4882a593Smuzhiyun     s8 release_level;
219*4882a593Smuzhiyun 
220*4882a593Smuzhiyun     u8 attack_velocity:7;
221*4882a593Smuzhiyun     u8 Unused7:1;
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun     u8 volume_velocity:7;
224*4882a593Smuzhiyun     u8 Unused8:1;
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun     u8 keyboard_scaling:7;
227*4882a593Smuzhiyun     u8 Unused9:1;
228*4882a593Smuzhiyun };
229*4882a593Smuzhiyun typedef struct wf_envelope wavefront_envelope;
230*4882a593Smuzhiyun 
231*4882a593Smuzhiyun struct wf_lfo
232*4882a593Smuzhiyun {
233*4882a593Smuzhiyun     u8 sample_number;
234*4882a593Smuzhiyun 
235*4882a593Smuzhiyun     u8 frequency:7;
236*4882a593Smuzhiyun     u8 Unused1:1;
237*4882a593Smuzhiyun 
238*4882a593Smuzhiyun     u8 am_src:4;
239*4882a593Smuzhiyun     u8 fm_src:4;
240*4882a593Smuzhiyun 
241*4882a593Smuzhiyun     s8 fm_amount;
242*4882a593Smuzhiyun     s8 am_amount;
243*4882a593Smuzhiyun     s8 start_level;
244*4882a593Smuzhiyun     s8 end_level;
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun     u8 ramp_delay:7;
247*4882a593Smuzhiyun     u8 wave_restart:1; /* for LFO2 only */
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun     u8 ramp_time:7;
250*4882a593Smuzhiyun     u8 Unused2:1;
251*4882a593Smuzhiyun };
252*4882a593Smuzhiyun typedef struct wf_lfo wavefront_lfo;
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun struct wf_patch
255*4882a593Smuzhiyun {
256*4882a593Smuzhiyun     s16  frequency_bias;         /*  ** THIS IS IN MOTOROLA FORMAT!! ** */
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun     u8 amplitude_bias:7;
259*4882a593Smuzhiyun     u8 Unused1:1;
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun     u8 portamento:7;
262*4882a593Smuzhiyun     u8 Unused2:1;
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun     u8 sample_number;
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun     u8 pitch_bend:4;
267*4882a593Smuzhiyun     u8 sample_msb:1;
268*4882a593Smuzhiyun     u8 Unused3:3;
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun     u8 mono:1;
271*4882a593Smuzhiyun     u8 retrigger:1;
272*4882a593Smuzhiyun     u8 nohold:1;
273*4882a593Smuzhiyun     u8 restart:1;
274*4882a593Smuzhiyun     u8 filterconfig:2; /* SDK says "not used" */
275*4882a593Smuzhiyun     u8 reuse:1;
276*4882a593Smuzhiyun     u8 reset_lfo:1;
277*4882a593Smuzhiyun 
278*4882a593Smuzhiyun     u8 fm_src2:4;
279*4882a593Smuzhiyun     u8 fm_src1:4;
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun     s8 fm_amount1;
282*4882a593Smuzhiyun     s8 fm_amount2;
283*4882a593Smuzhiyun 
284*4882a593Smuzhiyun     u8 am_src:4;
285*4882a593Smuzhiyun     u8 Unused4:4;
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun     s8 am_amount;
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun     u8 fc1_mode:4;
290*4882a593Smuzhiyun     u8 fc2_mode:4;
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun     s8 fc1_mod_amount;
293*4882a593Smuzhiyun     s8 fc1_keyboard_scaling;
294*4882a593Smuzhiyun     s8 fc1_bias;
295*4882a593Smuzhiyun     s8 fc2_mod_amount;
296*4882a593Smuzhiyun     s8 fc2_keyboard_scaling;
297*4882a593Smuzhiyun     s8 fc2_bias;
298*4882a593Smuzhiyun 
299*4882a593Smuzhiyun     u8 randomizer:7;
300*4882a593Smuzhiyun     u8 Unused5:1;
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun     struct wf_envelope envelope1;
303*4882a593Smuzhiyun     struct wf_envelope envelope2;
304*4882a593Smuzhiyun     struct wf_lfo lfo1;
305*4882a593Smuzhiyun     struct wf_lfo lfo2;
306*4882a593Smuzhiyun };
307*4882a593Smuzhiyun typedef struct wf_patch wavefront_patch;
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun struct wf_layer
310*4882a593Smuzhiyun {
311*4882a593Smuzhiyun     u8 patch_number;
312*4882a593Smuzhiyun 
313*4882a593Smuzhiyun     u8 mix_level:7;
314*4882a593Smuzhiyun     u8 mute:1;
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun     u8 split_point:7;
317*4882a593Smuzhiyun     u8 play_below:1;
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun     u8 pan_mod_src:2;
320*4882a593Smuzhiyun     u8 pan_or_mod:1;
321*4882a593Smuzhiyun     u8 pan:4;
322*4882a593Smuzhiyun     u8 split_type:1;
323*4882a593Smuzhiyun };
324*4882a593Smuzhiyun typedef struct wf_layer wavefront_layer;
325*4882a593Smuzhiyun 
326*4882a593Smuzhiyun struct wf_program
327*4882a593Smuzhiyun {
328*4882a593Smuzhiyun     struct wf_layer layer[WF_NUM_LAYERS];
329*4882a593Smuzhiyun };
330*4882a593Smuzhiyun typedef struct wf_program wavefront_program;
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun struct wf_sample_offset
333*4882a593Smuzhiyun {
334*4882a593Smuzhiyun     s32 Fraction:4;
335*4882a593Smuzhiyun     s32 Integer:20;
336*4882a593Smuzhiyun     s32 Unused:8;
337*4882a593Smuzhiyun };
338*4882a593Smuzhiyun typedef struct wf_sample_offset wavefront_sample_offset;
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun /* Sample slot types */
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun #define WF_ST_SAMPLE      0
343*4882a593Smuzhiyun #define WF_ST_MULTISAMPLE 1
344*4882a593Smuzhiyun #define WF_ST_ALIAS       2
345*4882a593Smuzhiyun #define WF_ST_EMPTY       3
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun /* pseudo's */
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun #define WF_ST_DRUM        4
350*4882a593Smuzhiyun #define WF_ST_PROGRAM     5
351*4882a593Smuzhiyun #define WF_ST_PATCH       6
352*4882a593Smuzhiyun #define WF_ST_SAMPLEHDR   7
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun #define WF_ST_MASK        0xf
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun /* Flags for slot status. These occupy the upper bits of the same byte
357*4882a593Smuzhiyun    as a sample type.
358*4882a593Smuzhiyun */
359*4882a593Smuzhiyun 
360*4882a593Smuzhiyun #define WF_SLOT_USED      0x80   /* XXX don't rely on this being accurate */
361*4882a593Smuzhiyun #define WF_SLOT_FILLED    0x40
362*4882a593Smuzhiyun #define WF_SLOT_ROM       0x20
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun #define WF_SLOT_MASK      0xf0
365*4882a593Smuzhiyun 
366*4882a593Smuzhiyun /* channel constants */
367*4882a593Smuzhiyun 
368*4882a593Smuzhiyun #define WF_CH_MONO  0
369*4882a593Smuzhiyun #define WF_CH_LEFT  1
370*4882a593Smuzhiyun #define WF_CH_RIGHT 2
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun /* Sample formats */
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun #define LINEAR_16BIT 0
375*4882a593Smuzhiyun #define WHITE_NOISE  1
376*4882a593Smuzhiyun #define LINEAR_8BIT  2
377*4882a593Smuzhiyun #define MULAW_8BIT   3
378*4882a593Smuzhiyun 
379*4882a593Smuzhiyun #define WF_SAMPLE_IS_8BIT(smpl) ((smpl)->SampleResolution&2)
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun 
382*4882a593Smuzhiyun /*
383*4882a593Smuzhiyun 
384*4882a593Smuzhiyun   Because most/all of the sample data we pass in via pointers has
385*4882a593Smuzhiyun   never been copied (just mmap-ed into user space straight from the
386*4882a593Smuzhiyun   disk), it would be nice to allow handling of multi-channel sample
387*4882a593Smuzhiyun   data without forcing user-level extraction of the relevant bytes.
388*4882a593Smuzhiyun 
389*4882a593Smuzhiyun   So, we need a way of specifying which channel to use (the WaveFront
390*4882a593Smuzhiyun   only handles mono samples in a given slot), and the only way to do
391*4882a593Smuzhiyun   this without using some struct other than wavefront_sample as the
392*4882a593Smuzhiyun   interface is the awful hack of using the unused bits in a
393*4882a593Smuzhiyun   wavefront_sample:
394*4882a593Smuzhiyun 
395*4882a593Smuzhiyun   Val      Meaning
396*4882a593Smuzhiyun   ---      -------
397*4882a593Smuzhiyun   0        no channel selection (use channel 1, sample is MONO)
398*4882a593Smuzhiyun   1        use first channel, and skip one
399*4882a593Smuzhiyun   2        use second channel, and skip one
400*4882a593Smuzhiyun   3        use third channel, and skip two
401*4882a593Smuzhiyun   4        use fourth channel, skip three
402*4882a593Smuzhiyun   5        use fifth channel, skip four
403*4882a593Smuzhiyun   6        use six channel, skip five
404*4882a593Smuzhiyun 
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun   This can handle up to 4 channels, and anyone downloading >4 channels
407*4882a593Smuzhiyun   of sample data just to select one of them needs to find some tools
408*4882a593Smuzhiyun   like sox ...
409*4882a593Smuzhiyun 
410*4882a593Smuzhiyun   NOTE: values 0, 1 and 2 correspond to WF_CH_* above. This is
411*4882a593Smuzhiyun   important.
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun */
414*4882a593Smuzhiyun 
415*4882a593Smuzhiyun #define WF_SET_CHANNEL(samp,chn) \
416*4882a593Smuzhiyun  (samp)->Unused1 = chn & 0x1; \
417*4882a593Smuzhiyun  (samp)->Unused2 = chn & 0x2; \
418*4882a593Smuzhiyun  (samp)->Unused3 = chn & 0x4
419*4882a593Smuzhiyun 
420*4882a593Smuzhiyun #define WF_GET_CHANNEL(samp) \
421*4882a593Smuzhiyun   (((samp)->Unused3 << 2)|((samp)->Unused2<<1)|(samp)->Unused1)
422*4882a593Smuzhiyun 
423*4882a593Smuzhiyun typedef struct wf_sample {
424*4882a593Smuzhiyun     struct wf_sample_offset sampleStartOffset;
425*4882a593Smuzhiyun     struct wf_sample_offset loopStartOffset;
426*4882a593Smuzhiyun     struct wf_sample_offset loopEndOffset;
427*4882a593Smuzhiyun     struct wf_sample_offset sampleEndOffset;
428*4882a593Smuzhiyun     s16 FrequencyBias;
429*4882a593Smuzhiyun     u8 SampleResolution:2;  /* sample_format */
430*4882a593Smuzhiyun     u8 Unused1:1;
431*4882a593Smuzhiyun     u8 Loop:1;
432*4882a593Smuzhiyun     u8 Bidirectional:1;
433*4882a593Smuzhiyun     u8 Unused2:1;
434*4882a593Smuzhiyun     u8 Reverse:1;
435*4882a593Smuzhiyun     u8 Unused3:1;
436*4882a593Smuzhiyun } wavefront_sample;
437*4882a593Smuzhiyun 
438*4882a593Smuzhiyun typedef struct wf_multisample {
439*4882a593Smuzhiyun     s16 NumberOfSamples;   /* log2 of the number of samples */
440*4882a593Smuzhiyun     s16 SampleNumber[NUM_MIDIKEYS];
441*4882a593Smuzhiyun } wavefront_multisample;
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun typedef struct wf_alias {
444*4882a593Smuzhiyun     s16 OriginalSample;
445*4882a593Smuzhiyun 
446*4882a593Smuzhiyun     struct wf_sample_offset sampleStartOffset;
447*4882a593Smuzhiyun     struct wf_sample_offset loopStartOffset;
448*4882a593Smuzhiyun     struct wf_sample_offset sampleEndOffset;
449*4882a593Smuzhiyun     struct wf_sample_offset loopEndOffset;
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun     s16  FrequencyBias;
452*4882a593Smuzhiyun 
453*4882a593Smuzhiyun     u8 SampleResolution:2;
454*4882a593Smuzhiyun     u8 Unused1:1;
455*4882a593Smuzhiyun     u8 Loop:1;
456*4882a593Smuzhiyun     u8 Bidirectional:1;
457*4882a593Smuzhiyun     u8 Unused2:1;
458*4882a593Smuzhiyun     u8 Reverse:1;
459*4882a593Smuzhiyun     u8 Unused3:1;
460*4882a593Smuzhiyun 
461*4882a593Smuzhiyun     /* This structure is meant to be padded only to 16 bits on their
462*4882a593Smuzhiyun        original. Of course, whoever wrote their documentation didn't
463*4882a593Smuzhiyun        realize that sizeof(struct) can be >=
464*4882a593Smuzhiyun        sum(sizeof(struct-fields)) and so thought that giving a C level
465*4882a593Smuzhiyun        description of the structs used in WavePatch files was
466*4882a593Smuzhiyun        sufficient. I suppose it was, as long as you remember the
467*4882a593Smuzhiyun        standard 16->32 bit issues.
468*4882a593Smuzhiyun     */
469*4882a593Smuzhiyun 
470*4882a593Smuzhiyun     u8 sixteen_bit_padding;
471*4882a593Smuzhiyun } __attribute__((packed)) wavefront_alias;
472*4882a593Smuzhiyun 
473*4882a593Smuzhiyun typedef struct wf_drum {
474*4882a593Smuzhiyun     u8 PatchNumber;
475*4882a593Smuzhiyun     u8 MixLevel:7;
476*4882a593Smuzhiyun     u8 Unmute:1;
477*4882a593Smuzhiyun     u8 Group:4;
478*4882a593Smuzhiyun     u8 Unused1:4;
479*4882a593Smuzhiyun     u8 PanModSource:2;
480*4882a593Smuzhiyun     u8 PanModulated:1;
481*4882a593Smuzhiyun     u8 PanAmount:4;
482*4882a593Smuzhiyun     u8 Unused2:1;
483*4882a593Smuzhiyun } wavefront_drum;
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun typedef struct wf_drumkit {
486*4882a593Smuzhiyun     struct wf_drum drum[NUM_MIDIKEYS];
487*4882a593Smuzhiyun } wavefront_drumkit;
488*4882a593Smuzhiyun 
489*4882a593Smuzhiyun typedef struct wf_channel_programs {
490*4882a593Smuzhiyun     u8 Program[NUM_MIDICHANNELS];
491*4882a593Smuzhiyun } wavefront_channel_programs;
492*4882a593Smuzhiyun 
493*4882a593Smuzhiyun /* How to get MIDI channel status from the data returned by
494*4882a593Smuzhiyun    a WFC_GET_CHANNEL_STATUS command (a struct wf_channel_programs)
495*4882a593Smuzhiyun */
496*4882a593Smuzhiyun 
497*4882a593Smuzhiyun #define WF_CHANNEL_STATUS(ch,wcp) (wcp)[(ch/7)] & (1<<((ch)%7))
498*4882a593Smuzhiyun 
499*4882a593Smuzhiyun typedef union wf_any {
500*4882a593Smuzhiyun     wavefront_sample s;
501*4882a593Smuzhiyun     wavefront_multisample ms;
502*4882a593Smuzhiyun     wavefront_alias a;
503*4882a593Smuzhiyun     wavefront_program pr;
504*4882a593Smuzhiyun     wavefront_patch p;
505*4882a593Smuzhiyun     wavefront_drum d;
506*4882a593Smuzhiyun } wavefront_any;
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun /* Hannu Solvainen hoped that his "patch_info" struct in soundcard.h
509*4882a593Smuzhiyun    might work for other wave-table based patch loading situations.
510*4882a593Smuzhiyun    Alas, his fears were correct. The WaveFront doesn't even come with
511*4882a593Smuzhiyun    just "patches", but several different kind of structures that
512*4882a593Smuzhiyun    control the sound generation process.
513*4882a593Smuzhiyun  */
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun typedef struct wf_patch_info {
516*4882a593Smuzhiyun 
517*4882a593Smuzhiyun     /* the first two fields are used by the OSS "patch loading" interface
518*4882a593Smuzhiyun        only, and are unused by the current user-level library.
519*4882a593Smuzhiyun     */
520*4882a593Smuzhiyun 
521*4882a593Smuzhiyun     s16   key;               /* Use WAVEFRONT_PATCH here */
522*4882a593Smuzhiyun     u16  devno;             /* fill in when sending */
523*4882a593Smuzhiyun     u8  subkey;            /* WF_ST_{SAMPLE,ALIAS,etc.} */
524*4882a593Smuzhiyun 
525*4882a593Smuzhiyun #define WAVEFRONT_FIND_FREE_SAMPLE_SLOT 999
526*4882a593Smuzhiyun 
527*4882a593Smuzhiyun     u16  number;            /* patch/sample/prog number */
528*4882a593Smuzhiyun 
529*4882a593Smuzhiyun     u32  size;              /* size of any data included in
530*4882a593Smuzhiyun 				  one of the fields in `hdrptr', or
531*4882a593Smuzhiyun 				  as `dataptr'.
532*4882a593Smuzhiyun 
533*4882a593Smuzhiyun 				  NOTE: for actual samples, this is
534*4882a593Smuzhiyun 				  the size of the *SELECTED CHANNEL*
535*4882a593Smuzhiyun 				  even if more data is actually available.
536*4882a593Smuzhiyun 
537*4882a593Smuzhiyun 				  So, a stereo sample (2 channels) of
538*4882a593Smuzhiyun 				  6000 bytes total has `size' = 3000.
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun 				  See the macros and comments for
541*4882a593Smuzhiyun 				  WF_{GET,SET}_CHANNEL above.
542*4882a593Smuzhiyun 
543*4882a593Smuzhiyun 			       */
544*4882a593Smuzhiyun     wavefront_any __user *hdrptr;      /* user-space ptr to hdr bytes */
545*4882a593Smuzhiyun     u16 __user *dataptr;            /* actual sample data */
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun     wavefront_any hdr;          /* kernel-space copy of hdr bytes */
548*4882a593Smuzhiyun } wavefront_patch_info;
549*4882a593Smuzhiyun 
550*4882a593Smuzhiyun /* The maximum number of bytes we will ever move to or from user space
551*4882a593Smuzhiyun    in response to a WFC_* command.  This obviously doesn't cover
552*4882a593Smuzhiyun    actual sample data.
553*4882a593Smuzhiyun */
554*4882a593Smuzhiyun 
555*4882a593Smuzhiyun #define WF_MAX_READ sizeof(wavefront_multisample)
556*4882a593Smuzhiyun #define WF_MAX_WRITE sizeof(wavefront_multisample)
557*4882a593Smuzhiyun 
558*4882a593Smuzhiyun /*
559*4882a593Smuzhiyun    This allows us to execute any WF command except the download/upload
560*4882a593Smuzhiyun    ones, which are handled differently due to copyin/copyout issues as
561*4882a593Smuzhiyun    well as data-nybbling to/from the card.
562*4882a593Smuzhiyun  */
563*4882a593Smuzhiyun 
564*4882a593Smuzhiyun typedef struct wavefront_control {
565*4882a593Smuzhiyun     int cmd;                           /* WFC_* */
566*4882a593Smuzhiyun     char status;                       /* return status to user-space */
567*4882a593Smuzhiyun     unsigned char rbuf[WF_MAX_READ];   /* bytes read from card */
568*4882a593Smuzhiyun     unsigned char wbuf[WF_MAX_WRITE];  /* bytes written to card */
569*4882a593Smuzhiyun } wavefront_control;
570*4882a593Smuzhiyun 
571*4882a593Smuzhiyun #define WFCTL_WFCMD    0x1
572*4882a593Smuzhiyun #define WFCTL_LOAD_SPP 0x2
573*4882a593Smuzhiyun 
574*4882a593Smuzhiyun /* Modulator table */
575*4882a593Smuzhiyun 
576*4882a593Smuzhiyun #define WF_MOD_LFO1      0
577*4882a593Smuzhiyun #define WF_MOD_LFO2      1
578*4882a593Smuzhiyun #define WF_MOD_ENV1      2
579*4882a593Smuzhiyun #define WF_MOD_ENV2      3
580*4882a593Smuzhiyun #define WF_MOD_KEYBOARD  4
581*4882a593Smuzhiyun #define WF_MOD_LOGKEY    5
582*4882a593Smuzhiyun #define WF_MOD_VELOCITY  6
583*4882a593Smuzhiyun #define WF_MOD_LOGVEL    7
584*4882a593Smuzhiyun #define WF_MOD_RANDOM    8
585*4882a593Smuzhiyun #define WF_MOD_PRESSURE  9
586*4882a593Smuzhiyun #define WF_MOD_MOD_WHEEL 10
587*4882a593Smuzhiyun #define WF_MOD_1         WF_MOD_MOD_WHEEL
588*4882a593Smuzhiyun #define WF_MOD_BREATH    11
589*4882a593Smuzhiyun #define WF_MOD_2         WF_MOD_BREATH
590*4882a593Smuzhiyun #define WF_MOD_FOOT      12
591*4882a593Smuzhiyun #define WF_MOD_4         WF_MOD_FOOT
592*4882a593Smuzhiyun #define WF_MOD_VOLUME    13
593*4882a593Smuzhiyun #define WF_MOD_7         WF_MOD_VOLUME
594*4882a593Smuzhiyun #define WF_MOD_PAN       14
595*4882a593Smuzhiyun #define WF_MOD_10        WF_MOD_PAN
596*4882a593Smuzhiyun #define WF_MOD_EXPR      15
597*4882a593Smuzhiyun #define WF_MOD_11        WF_MOD_EXPR
598*4882a593Smuzhiyun 
599*4882a593Smuzhiyun /* FX-related material */
600*4882a593Smuzhiyun 
601*4882a593Smuzhiyun typedef struct wf_fx_info {
602*4882a593Smuzhiyun     int request;             /* see list below */
603*4882a593Smuzhiyun     long data[4];             /* we don't need much */
604*4882a593Smuzhiyun } wavefront_fx_info;
605*4882a593Smuzhiyun 
606*4882a593Smuzhiyun /* support for each of these will be forthcoming once I or someone
607*4882a593Smuzhiyun    else has figured out which of the addresses on page 6 and page 7 of
608*4882a593Smuzhiyun    the YSS225 control each parameter. Incidentally, these come from
609*4882a593Smuzhiyun    the Windows driver interface, but again, Turtle Beach didn't
610*4882a593Smuzhiyun    document the API to use them.
611*4882a593Smuzhiyun */
612*4882a593Smuzhiyun 
613*4882a593Smuzhiyun #define WFFX_SETOUTGAIN		        0
614*4882a593Smuzhiyun #define WFFX_SETSTEREOOUTGAIN		1
615*4882a593Smuzhiyun #define WFFX_SETREVERBIN1GAIN		2
616*4882a593Smuzhiyun #define WFFX_SETREVERBIN2GAIN		3
617*4882a593Smuzhiyun #define WFFX_SETREVERBIN3GAIN		4
618*4882a593Smuzhiyun #define WFFX_SETCHORUSINPORT		5
619*4882a593Smuzhiyun #define WFFX_SETREVERBIN1PORT		6
620*4882a593Smuzhiyun #define WFFX_SETREVERBIN2PORT		7
621*4882a593Smuzhiyun #define WFFX_SETREVERBIN3PORT		8
622*4882a593Smuzhiyun #define WFFX_SETEFFECTPORT		9
623*4882a593Smuzhiyun #define WFFX_SETAUXPORT		        10
624*4882a593Smuzhiyun #define WFFX_SETREVERBTYPE		11
625*4882a593Smuzhiyun #define WFFX_SETREVERBDELAY		12
626*4882a593Smuzhiyun #define WFFX_SETCHORUSLFO		13
627*4882a593Smuzhiyun #define WFFX_SETCHORUSPMD		14
628*4882a593Smuzhiyun #define WFFX_SETCHORUSAMD		15
629*4882a593Smuzhiyun #define WFFX_SETEFFECT		        16
630*4882a593Smuzhiyun #define WFFX_SETBASEALL		        17
631*4882a593Smuzhiyun #define WFFX_SETREVERBALL		18
632*4882a593Smuzhiyun #define WFFX_SETCHORUSALL		20
633*4882a593Smuzhiyun #define WFFX_SETREVERBDEF		22
634*4882a593Smuzhiyun #define WFFX_SETCHORUSDEF		23
635*4882a593Smuzhiyun #define WFFX_DELAYSETINGAIN		24
636*4882a593Smuzhiyun #define WFFX_DELAYSETFBGAIN	        25
637*4882a593Smuzhiyun #define WFFX_DELAYSETFBLPF		26
638*4882a593Smuzhiyun #define WFFX_DELAYSETGAIN		27
639*4882a593Smuzhiyun #define WFFX_DELAYSETTIME		28
640*4882a593Smuzhiyun #define WFFX_DELAYSETFBTIME		29
641*4882a593Smuzhiyun #define WFFX_DELAYSETALL		30
642*4882a593Smuzhiyun #define WFFX_DELAYSETDEF		32
643*4882a593Smuzhiyun #define WFFX_SDELAYSETINGAIN		33
644*4882a593Smuzhiyun #define WFFX_SDELAYSETFBGAIN		34
645*4882a593Smuzhiyun #define WFFX_SDELAYSETFBLPF		35
646*4882a593Smuzhiyun #define WFFX_SDELAYSETGAIN		36
647*4882a593Smuzhiyun #define WFFX_SDELAYSETTIME		37
648*4882a593Smuzhiyun #define WFFX_SDELAYSETFBTIME		38
649*4882a593Smuzhiyun #define WFFX_SDELAYSETALL		39
650*4882a593Smuzhiyun #define WFFX_SDELAYSETDEF		41
651*4882a593Smuzhiyun #define WFFX_DEQSETINGAIN		42
652*4882a593Smuzhiyun #define WFFX_DEQSETFILTER		43
653*4882a593Smuzhiyun #define WFFX_DEQSETALL		        44
654*4882a593Smuzhiyun #define WFFX_DEQSETDEF		        46
655*4882a593Smuzhiyun #define WFFX_MUTE		        47
656*4882a593Smuzhiyun #define WFFX_FLANGESETBALANCE	        48
657*4882a593Smuzhiyun #define WFFX_FLANGESETDELAY		49
658*4882a593Smuzhiyun #define WFFX_FLANGESETDWFFX_TH		50
659*4882a593Smuzhiyun #define WFFX_FLANGESETFBGAIN		51
660*4882a593Smuzhiyun #define WFFX_FLANGESETINGAIN		52
661*4882a593Smuzhiyun #define WFFX_FLANGESETLFO		53
662*4882a593Smuzhiyun #define WFFX_FLANGESETALL		54
663*4882a593Smuzhiyun #define WFFX_FLANGESETDEF		56
664*4882a593Smuzhiyun #define WFFX_PITCHSETSHIFT		57
665*4882a593Smuzhiyun #define WFFX_PITCHSETBALANCE		58
666*4882a593Smuzhiyun #define WFFX_PITCHSETALL		59
667*4882a593Smuzhiyun #define WFFX_PITCHSETDEF		61
668*4882a593Smuzhiyun #define WFFX_SRSSETINGAIN		62
669*4882a593Smuzhiyun #define WFFX_SRSSETSPACE		63
670*4882a593Smuzhiyun #define WFFX_SRSSETCENTER		64
671*4882a593Smuzhiyun #define WFFX_SRSSETGAIN		        65
672*4882a593Smuzhiyun #define WFFX_SRSSETMODE	        	66
673*4882a593Smuzhiyun #define WFFX_SRSSETDEF		        68
674*4882a593Smuzhiyun 
675*4882a593Smuzhiyun /* Allow direct user-space control over FX memory/coefficient data.
676*4882a593Smuzhiyun    In theory this could be used to download the FX microprogram,
677*4882a593Smuzhiyun    but it would be a little slower, and involve some weird code.
678*4882a593Smuzhiyun  */
679*4882a593Smuzhiyun 
680*4882a593Smuzhiyun #define WFFX_MEMSET              69
681*4882a593Smuzhiyun 
682*4882a593Smuzhiyun #endif /* __SOUND_WAVEFRONT_H__ */
683