162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */
262306a36Sopenharmony_ci#ifndef __SOUND_WAVEFRONT_H__
362306a36Sopenharmony_ci#define __SOUND_WAVEFRONT_H__
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci/*
662306a36Sopenharmony_ci *  Driver for Turtle Beach Wavefront cards (Maui,Tropez,Tropez+)
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci *  Copyright (c) by Paul Barton-Davis <pbd@op.net>
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#if (!defined(__GNUC__) && !defined(__GNUG__))
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci     You will not be able to compile this file correctly without gcc, because
1462306a36Sopenharmony_ci     it is necessary to pack the "wavefront_alias" structure to a size
1562306a36Sopenharmony_ci     of 22 bytes, corresponding to 16-bit alignment (as would have been
1662306a36Sopenharmony_ci     the case on the original platform, MS-DOS). If this is not done,
1762306a36Sopenharmony_ci     then WavePatch-format files cannot be read/written correctly.
1862306a36Sopenharmony_ci     The method used to do this here ("__attribute__((packed)") is
1962306a36Sopenharmony_ci     completely compiler dependent.
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci     All other wavefront_* types end up aligned to 32 bit values and
2262306a36Sopenharmony_ci     still have the same (correct) size.
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci#else
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci     /* However, note that as of G++ 2.7.3.2, g++ was unable to
2762306a36Sopenharmony_ci	correctly parse *type* __attribute__ tags. It will do the
2862306a36Sopenharmony_ci	right thing if we use the "packed" attribute on each struct
2962306a36Sopenharmony_ci	member, which has the same semantics anyway.
3062306a36Sopenharmony_ci     */
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci#endif /* __GNUC__ */
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_ci/***************************** WARNING ********************************
3562306a36Sopenharmony_ci  PLEASE DO NOT MODIFY THIS FILE IN ANY WAY THAT AFFECTS ITS ABILITY TO
3662306a36Sopenharmony_ci  BE USED WITH EITHER C *OR* C++.
3762306a36Sopenharmony_ci **********************************************************************/
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci#ifndef NUM_MIDIKEYS
4062306a36Sopenharmony_ci#define NUM_MIDIKEYS 128
4162306a36Sopenharmony_ci#endif  /* NUM_MIDIKEYS */
4262306a36Sopenharmony_ci
4362306a36Sopenharmony_ci#ifndef NUM_MIDICHANNELS
4462306a36Sopenharmony_ci#define NUM_MIDICHANNELS 16
4562306a36Sopenharmony_ci#endif  /* NUM_MIDICHANNELS */
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_ci/* These are very useful/important. the original wavefront interface
4862306a36Sopenharmony_ci   was developed on a 16 bit system, where sizeof(int) = 2
4962306a36Sopenharmony_ci   bytes. Defining things like this makes the code much more portable, and
5062306a36Sopenharmony_ci   easier to understand without having to toggle back and forth
5162306a36Sopenharmony_ci   between a 16-bit view of the world and a 32-bit one.
5262306a36Sopenharmony_ci */
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci#ifndef __KERNEL__
5562306a36Sopenharmony_ci/* keep them for compatibility */
5662306a36Sopenharmony_citypedef short s16;
5762306a36Sopenharmony_citypedef unsigned short u16;
5862306a36Sopenharmony_citypedef int s32;
5962306a36Sopenharmony_citypedef unsigned int u32;
6062306a36Sopenharmony_citypedef char s8;
6162306a36Sopenharmony_citypedef unsigned char u8;
6262306a36Sopenharmony_citypedef s16 INT16;
6362306a36Sopenharmony_citypedef u16 UINT16;
6462306a36Sopenharmony_citypedef s32 INT32;
6562306a36Sopenharmony_citypedef u32 UINT32;
6662306a36Sopenharmony_citypedef s8 CHAR8;
6762306a36Sopenharmony_citypedef u8 UCHAR8;
6862306a36Sopenharmony_ci#endif
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci/* Pseudo-commands not part of the WaveFront command set.
7162306a36Sopenharmony_ci   These are used for various driver controls and direct
7262306a36Sopenharmony_ci   hardware control.
7362306a36Sopenharmony_ci */
7462306a36Sopenharmony_ci
7562306a36Sopenharmony_ci#define WFC_DEBUG_DRIVER                0
7662306a36Sopenharmony_ci#define WFC_FX_IOCTL                    1
7762306a36Sopenharmony_ci#define WFC_PATCH_STATUS                2
7862306a36Sopenharmony_ci#define WFC_PROGRAM_STATUS              3
7962306a36Sopenharmony_ci#define WFC_SAMPLE_STATUS               4
8062306a36Sopenharmony_ci#define WFC_DISABLE_INTERRUPTS          5
8162306a36Sopenharmony_ci#define WFC_ENABLE_INTERRUPTS           6
8262306a36Sopenharmony_ci#define WFC_INTERRUPT_STATUS            7
8362306a36Sopenharmony_ci#define WFC_ROMSAMPLES_RDONLY           8
8462306a36Sopenharmony_ci#define WFC_IDENTIFY_SLOT_TYPE          9
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci/* Wavefront synth commands
8762306a36Sopenharmony_ci */
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci#define WFC_DOWNLOAD_SAMPLE		0x80
9062306a36Sopenharmony_ci#define WFC_DOWNLOAD_BLOCK		0x81
9162306a36Sopenharmony_ci#define WFC_DOWNLOAD_MULTISAMPLE	0x82
9262306a36Sopenharmony_ci#define WFC_DOWNLOAD_SAMPLE_ALIAS	0x83
9362306a36Sopenharmony_ci#define WFC_DELETE_SAMPLE		0x84
9462306a36Sopenharmony_ci#define WFC_REPORT_FREE_MEMORY		0x85
9562306a36Sopenharmony_ci#define WFC_DOWNLOAD_PATCH		0x86
9662306a36Sopenharmony_ci#define WFC_DOWNLOAD_PROGRAM		0x87
9762306a36Sopenharmony_ci#define WFC_SET_SYNTHVOL		0x89
9862306a36Sopenharmony_ci#define WFC_SET_NVOICES			0x8B
9962306a36Sopenharmony_ci#define WFC_DOWNLOAD_DRUM		0x90
10062306a36Sopenharmony_ci#define WFC_GET_SYNTHVOL		0x92
10162306a36Sopenharmony_ci#define WFC_GET_NVOICES			0x94
10262306a36Sopenharmony_ci#define WFC_DISABLE_CHANNEL		0x9A
10362306a36Sopenharmony_ci#define WFC_ENABLE_CHANNEL		0x9B
10462306a36Sopenharmony_ci#define WFC_MISYNTH_OFF			0x9D
10562306a36Sopenharmony_ci#define WFC_MISYNTH_ON			0x9E
10662306a36Sopenharmony_ci#define WFC_FIRMWARE_VERSION		0x9F
10762306a36Sopenharmony_ci#define WFC_GET_NSAMPLES		0xA0
10862306a36Sopenharmony_ci#define WFC_DISABLE_DRUM_PROGRAM	0xA2
10962306a36Sopenharmony_ci#define WFC_UPLOAD_PATCH		0xA3
11062306a36Sopenharmony_ci#define WFC_UPLOAD_PROGRAM		0xA4
11162306a36Sopenharmony_ci#define WFC_SET_TUNING			0xA6
11262306a36Sopenharmony_ci#define WFC_GET_TUNING			0xA7
11362306a36Sopenharmony_ci#define WFC_VMIDI_ON			0xA8
11462306a36Sopenharmony_ci#define WFC_VMIDI_OFF			0xA9
11562306a36Sopenharmony_ci#define WFC_MIDI_STATUS			0xAA
11662306a36Sopenharmony_ci#define WFC_GET_CHANNEL_STATUS		0xAB
11762306a36Sopenharmony_ci#define WFC_DOWNLOAD_SAMPLE_HEADER	0xAC
11862306a36Sopenharmony_ci#define WFC_UPLOAD_SAMPLE_HEADER	0xAD
11962306a36Sopenharmony_ci#define WFC_UPLOAD_MULTISAMPLE		0xAE
12062306a36Sopenharmony_ci#define WFC_UPLOAD_SAMPLE_ALIAS		0xAF
12162306a36Sopenharmony_ci#define WFC_IDENTIFY_SAMPLE_TYPE	0xB0
12262306a36Sopenharmony_ci#define WFC_DOWNLOAD_EDRUM_PROGRAM	0xB1
12362306a36Sopenharmony_ci#define WFC_UPLOAD_EDRUM_PROGRAM	0xB2
12462306a36Sopenharmony_ci#define WFC_SET_EDRUM_CHANNEL		0xB3
12562306a36Sopenharmony_ci#define WFC_INSTOUT_LEVELS		0xB4
12662306a36Sopenharmony_ci#define WFC_PEAKOUT_LEVELS		0xB5
12762306a36Sopenharmony_ci#define WFC_REPORT_CHANNEL_PROGRAMS	0xB6
12862306a36Sopenharmony_ci#define WFC_HARDWARE_VERSION		0xCF
12962306a36Sopenharmony_ci#define WFC_UPLOAD_SAMPLE_PARAMS	0xD7
13062306a36Sopenharmony_ci#define WFC_DOWNLOAD_OS			0xF1
13162306a36Sopenharmony_ci#define WFC_NOOP                        0xFF
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci#define WF_MAX_SAMPLE   512
13462306a36Sopenharmony_ci#define WF_MAX_PATCH    256
13562306a36Sopenharmony_ci#define WF_MAX_PROGRAM  128
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci#define WF_SECTION_MAX  44   /* longest OS section length */
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci/* # of bytes we send to the board when sending it various kinds of
14062306a36Sopenharmony_ci   substantive data, such as samples, patches and programs.
14162306a36Sopenharmony_ci*/
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci#define WF_PROGRAM_BYTES 32
14462306a36Sopenharmony_ci#define WF_PATCH_BYTES 132
14562306a36Sopenharmony_ci#define WF_SAMPLE_BYTES 27
14662306a36Sopenharmony_ci#define WF_SAMPLE_HDR_BYTES 25
14762306a36Sopenharmony_ci#define WF_ALIAS_BYTES 25
14862306a36Sopenharmony_ci#define WF_DRUM_BYTES 9
14962306a36Sopenharmony_ci#define WF_MSAMPLE_BYTES 259 /* (MIDI_KEYS * 2) + 3 */
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci#define WF_ACK     0x80
15262306a36Sopenharmony_ci#define WF_DMA_ACK 0x81
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci/* OR-values for MIDI status bits */
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci#define WF_MIDI_VIRTUAL_ENABLED 0x1
15762306a36Sopenharmony_ci#define WF_MIDI_VIRTUAL_IS_EXTERNAL 0x2
15862306a36Sopenharmony_ci#define WF_MIDI_IN_TO_SYNTH_DISABLED 0x4
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci/* slot indexes for struct address_info: makes code a little more mnemonic */
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_ci#define WF_SYNTH_SLOT         0
16362306a36Sopenharmony_ci#define WF_INTERNAL_MIDI_SLOT 1
16462306a36Sopenharmony_ci#define WF_EXTERNAL_MIDI_SLOT 2
16562306a36Sopenharmony_ci
16662306a36Sopenharmony_ci/* Magic MIDI bytes used to switch I/O streams on the ICS2115 MPU401
16762306a36Sopenharmony_ci   emulation. Note these NEVER show up in output from the device and
16862306a36Sopenharmony_ci   should NEVER be used in input unless Virtual MIDI mode has been
16962306a36Sopenharmony_ci   disabled. If they do show up as input, the results are unpredictable.
17062306a36Sopenharmony_ci*/
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci#define WF_EXTERNAL_SWITCH  0xFD
17362306a36Sopenharmony_ci#define WF_INTERNAL_SWITCH  0xF9
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci/* Debugging flags */
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci#define WF_DEBUG_CMD 0x1
17862306a36Sopenharmony_ci#define WF_DEBUG_DATA 0x2
17962306a36Sopenharmony_ci#define WF_DEBUG_LOAD_PATCH 0x4
18062306a36Sopenharmony_ci#define WF_DEBUG_IO 0x8
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci/* WavePatch file format stuff */
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_ci#define WF_WAVEPATCH_VERSION     120;  /*  Current version number (1.2)  */
18562306a36Sopenharmony_ci#define WF_MAX_COMMENT           64    /*  Comment length */
18662306a36Sopenharmony_ci#define WF_NUM_LAYERS            4
18762306a36Sopenharmony_ci#define WF_NAME_LENGTH           32
18862306a36Sopenharmony_ci#define WF_SOURCE_LENGTH         260
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci#define BankFileID     "Bank"
19162306a36Sopenharmony_ci#define DrumkitFileID  "DrumKit"
19262306a36Sopenharmony_ci#define ProgramFileID  "Program"
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_cistruct wf_envelope
19562306a36Sopenharmony_ci{
19662306a36Sopenharmony_ci    u8 attack_time:7;
19762306a36Sopenharmony_ci    u8 Unused1:1;
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_ci    u8 decay1_time:7;
20062306a36Sopenharmony_ci    u8 Unused2:1;
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci    u8 decay2_time:7;
20362306a36Sopenharmony_ci    u8 Unused3:1;
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci    u8 sustain_time:7;
20662306a36Sopenharmony_ci    u8 Unused4:1;
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ci    u8 release_time:7;
20962306a36Sopenharmony_ci    u8 Unused5:1;
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci    u8 release2_time:7;
21262306a36Sopenharmony_ci    u8 Unused6:1;
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci    s8 attack_level;
21562306a36Sopenharmony_ci    s8 decay1_level;
21662306a36Sopenharmony_ci    s8 decay2_level;
21762306a36Sopenharmony_ci    s8 sustain_level;
21862306a36Sopenharmony_ci    s8 release_level;
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ci    u8 attack_velocity:7;
22162306a36Sopenharmony_ci    u8 Unused7:1;
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci    u8 volume_velocity:7;
22462306a36Sopenharmony_ci    u8 Unused8:1;
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_ci    u8 keyboard_scaling:7;
22762306a36Sopenharmony_ci    u8 Unused9:1;
22862306a36Sopenharmony_ci};
22962306a36Sopenharmony_citypedef struct wf_envelope wavefront_envelope;
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_cistruct wf_lfo
23262306a36Sopenharmony_ci{
23362306a36Sopenharmony_ci    u8 sample_number;
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci    u8 frequency:7;
23662306a36Sopenharmony_ci    u8 Unused1:1;
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci    u8 am_src:4;
23962306a36Sopenharmony_ci    u8 fm_src:4;
24062306a36Sopenharmony_ci
24162306a36Sopenharmony_ci    s8 fm_amount;
24262306a36Sopenharmony_ci    s8 am_amount;
24362306a36Sopenharmony_ci    s8 start_level;
24462306a36Sopenharmony_ci    s8 end_level;
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ci    u8 ramp_delay:7;
24762306a36Sopenharmony_ci    u8 wave_restart:1; /* for LFO2 only */
24862306a36Sopenharmony_ci
24962306a36Sopenharmony_ci    u8 ramp_time:7;
25062306a36Sopenharmony_ci    u8 Unused2:1;
25162306a36Sopenharmony_ci};
25262306a36Sopenharmony_citypedef struct wf_lfo wavefront_lfo;
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_cistruct wf_patch
25562306a36Sopenharmony_ci{
25662306a36Sopenharmony_ci    s16  frequency_bias;         /*  ** THIS IS IN MOTOROLA FORMAT!! ** */
25762306a36Sopenharmony_ci
25862306a36Sopenharmony_ci    u8 amplitude_bias:7;
25962306a36Sopenharmony_ci    u8 Unused1:1;
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci    u8 portamento:7;
26262306a36Sopenharmony_ci    u8 Unused2:1;
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_ci    u8 sample_number;
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci    u8 pitch_bend:4;
26762306a36Sopenharmony_ci    u8 sample_msb:1;
26862306a36Sopenharmony_ci    u8 Unused3:3;
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci    u8 mono:1;
27162306a36Sopenharmony_ci    u8 retrigger:1;
27262306a36Sopenharmony_ci    u8 nohold:1;
27362306a36Sopenharmony_ci    u8 restart:1;
27462306a36Sopenharmony_ci    u8 filterconfig:2; /* SDK says "not used" */
27562306a36Sopenharmony_ci    u8 reuse:1;
27662306a36Sopenharmony_ci    u8 reset_lfo:1;
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_ci    u8 fm_src2:4;
27962306a36Sopenharmony_ci    u8 fm_src1:4;
28062306a36Sopenharmony_ci
28162306a36Sopenharmony_ci    s8 fm_amount1;
28262306a36Sopenharmony_ci    s8 fm_amount2;
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci    u8 am_src:4;
28562306a36Sopenharmony_ci    u8 Unused4:4;
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci    s8 am_amount;
28862306a36Sopenharmony_ci
28962306a36Sopenharmony_ci    u8 fc1_mode:4;
29062306a36Sopenharmony_ci    u8 fc2_mode:4;
29162306a36Sopenharmony_ci
29262306a36Sopenharmony_ci    s8 fc1_mod_amount;
29362306a36Sopenharmony_ci    s8 fc1_keyboard_scaling;
29462306a36Sopenharmony_ci    s8 fc1_bias;
29562306a36Sopenharmony_ci    s8 fc2_mod_amount;
29662306a36Sopenharmony_ci    s8 fc2_keyboard_scaling;
29762306a36Sopenharmony_ci    s8 fc2_bias;
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci    u8 randomizer:7;
30062306a36Sopenharmony_ci    u8 Unused5:1;
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci    struct wf_envelope envelope1;
30362306a36Sopenharmony_ci    struct wf_envelope envelope2;
30462306a36Sopenharmony_ci    struct wf_lfo lfo1;
30562306a36Sopenharmony_ci    struct wf_lfo lfo2;
30662306a36Sopenharmony_ci};
30762306a36Sopenharmony_citypedef struct wf_patch wavefront_patch;
30862306a36Sopenharmony_ci
30962306a36Sopenharmony_cistruct wf_layer
31062306a36Sopenharmony_ci{
31162306a36Sopenharmony_ci    u8 patch_number;
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci    u8 mix_level:7;
31462306a36Sopenharmony_ci    u8 mute:1;
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_ci    u8 split_point:7;
31762306a36Sopenharmony_ci    u8 play_below:1;
31862306a36Sopenharmony_ci
31962306a36Sopenharmony_ci    u8 pan_mod_src:2;
32062306a36Sopenharmony_ci    u8 pan_or_mod:1;
32162306a36Sopenharmony_ci    u8 pan:4;
32262306a36Sopenharmony_ci    u8 split_type:1;
32362306a36Sopenharmony_ci};
32462306a36Sopenharmony_citypedef struct wf_layer wavefront_layer;
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_cistruct wf_program
32762306a36Sopenharmony_ci{
32862306a36Sopenharmony_ci    struct wf_layer layer[WF_NUM_LAYERS];
32962306a36Sopenharmony_ci};
33062306a36Sopenharmony_citypedef struct wf_program wavefront_program;
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_cistruct wf_sample_offset
33362306a36Sopenharmony_ci{
33462306a36Sopenharmony_ci    s32 Fraction:4;
33562306a36Sopenharmony_ci    s32 Integer:20;
33662306a36Sopenharmony_ci    s32 Unused:8;
33762306a36Sopenharmony_ci};
33862306a36Sopenharmony_citypedef struct wf_sample_offset wavefront_sample_offset;
33962306a36Sopenharmony_ci
34062306a36Sopenharmony_ci/* Sample slot types */
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ci#define WF_ST_SAMPLE      0
34362306a36Sopenharmony_ci#define WF_ST_MULTISAMPLE 1
34462306a36Sopenharmony_ci#define WF_ST_ALIAS       2
34562306a36Sopenharmony_ci#define WF_ST_EMPTY       3
34662306a36Sopenharmony_ci
34762306a36Sopenharmony_ci/* pseudo's */
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci#define WF_ST_DRUM        4
35062306a36Sopenharmony_ci#define WF_ST_PROGRAM     5
35162306a36Sopenharmony_ci#define WF_ST_PATCH       6
35262306a36Sopenharmony_ci#define WF_ST_SAMPLEHDR   7
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci#define WF_ST_MASK        0xf
35562306a36Sopenharmony_ci
35662306a36Sopenharmony_ci/* Flags for slot status. These occupy the upper bits of the same byte
35762306a36Sopenharmony_ci   as a sample type.
35862306a36Sopenharmony_ci*/
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci#define WF_SLOT_USED      0x80   /* XXX don't rely on this being accurate */
36162306a36Sopenharmony_ci#define WF_SLOT_FILLED    0x40
36262306a36Sopenharmony_ci#define WF_SLOT_ROM       0x20
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci#define WF_SLOT_MASK      0xf0
36562306a36Sopenharmony_ci
36662306a36Sopenharmony_ci/* channel constants */
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_ci#define WF_CH_MONO  0
36962306a36Sopenharmony_ci#define WF_CH_LEFT  1
37062306a36Sopenharmony_ci#define WF_CH_RIGHT 2
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_ci/* Sample formats */
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci#define LINEAR_16BIT 0
37562306a36Sopenharmony_ci#define WHITE_NOISE  1
37662306a36Sopenharmony_ci#define LINEAR_8BIT  2
37762306a36Sopenharmony_ci#define MULAW_8BIT   3
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_ci#define WF_SAMPLE_IS_8BIT(smpl) ((smpl)->SampleResolution&2)
38062306a36Sopenharmony_ci
38162306a36Sopenharmony_ci
38262306a36Sopenharmony_ci/*
38362306a36Sopenharmony_ci
38462306a36Sopenharmony_ci  Because most/all of the sample data we pass in via pointers has
38562306a36Sopenharmony_ci  never been copied (just mmap-ed into user space straight from the
38662306a36Sopenharmony_ci  disk), it would be nice to allow handling of multi-channel sample
38762306a36Sopenharmony_ci  data without forcing user-level extraction of the relevant bytes.
38862306a36Sopenharmony_ci
38962306a36Sopenharmony_ci  So, we need a way of specifying which channel to use (the WaveFront
39062306a36Sopenharmony_ci  only handles mono samples in a given slot), and the only way to do
39162306a36Sopenharmony_ci  this without using some struct other than wavefront_sample as the
39262306a36Sopenharmony_ci  interface is the awful hack of using the unused bits in a
39362306a36Sopenharmony_ci  wavefront_sample:
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_ci  Val      Meaning
39662306a36Sopenharmony_ci  ---      -------
39762306a36Sopenharmony_ci  0        no channel selection (use channel 1, sample is MONO)
39862306a36Sopenharmony_ci  1        use first channel, and skip one
39962306a36Sopenharmony_ci  2        use second channel, and skip one
40062306a36Sopenharmony_ci  3        use third channel, and skip two
40162306a36Sopenharmony_ci  4        use fourth channel, skip three
40262306a36Sopenharmony_ci  5        use fifth channel, skip four
40362306a36Sopenharmony_ci  6        use six channel, skip five
40462306a36Sopenharmony_ci
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ci  This can handle up to 4 channels, and anyone downloading >4 channels
40762306a36Sopenharmony_ci  of sample data just to select one of them needs to find some tools
40862306a36Sopenharmony_ci  like sox ...
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_ci  NOTE: values 0, 1 and 2 correspond to WF_CH_* above. This is
41162306a36Sopenharmony_ci  important.
41262306a36Sopenharmony_ci
41362306a36Sopenharmony_ci*/
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ci#define WF_SET_CHANNEL(samp,chn) \
41662306a36Sopenharmony_ci (samp)->Unused1 = chn & 0x1; \
41762306a36Sopenharmony_ci (samp)->Unused2 = chn & 0x2; \
41862306a36Sopenharmony_ci (samp)->Unused3 = chn & 0x4
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_ci#define WF_GET_CHANNEL(samp) \
42162306a36Sopenharmony_ci  (((samp)->Unused3 << 2)|((samp)->Unused2<<1)|(samp)->Unused1)
42262306a36Sopenharmony_ci
42362306a36Sopenharmony_citypedef struct wf_sample {
42462306a36Sopenharmony_ci    struct wf_sample_offset sampleStartOffset;
42562306a36Sopenharmony_ci    struct wf_sample_offset loopStartOffset;
42662306a36Sopenharmony_ci    struct wf_sample_offset loopEndOffset;
42762306a36Sopenharmony_ci    struct wf_sample_offset sampleEndOffset;
42862306a36Sopenharmony_ci    s16 FrequencyBias;
42962306a36Sopenharmony_ci    u8 SampleResolution:2;  /* sample_format */
43062306a36Sopenharmony_ci    u8 Unused1:1;
43162306a36Sopenharmony_ci    u8 Loop:1;
43262306a36Sopenharmony_ci    u8 Bidirectional:1;
43362306a36Sopenharmony_ci    u8 Unused2:1;
43462306a36Sopenharmony_ci    u8 Reverse:1;
43562306a36Sopenharmony_ci    u8 Unused3:1;
43662306a36Sopenharmony_ci} wavefront_sample;
43762306a36Sopenharmony_ci
43862306a36Sopenharmony_citypedef struct wf_multisample {
43962306a36Sopenharmony_ci    s16 NumberOfSamples;   /* log2 of the number of samples */
44062306a36Sopenharmony_ci    s16 SampleNumber[NUM_MIDIKEYS];
44162306a36Sopenharmony_ci} wavefront_multisample;
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_citypedef struct wf_alias {
44462306a36Sopenharmony_ci    s16 OriginalSample;
44562306a36Sopenharmony_ci
44662306a36Sopenharmony_ci    struct wf_sample_offset sampleStartOffset;
44762306a36Sopenharmony_ci    struct wf_sample_offset loopStartOffset;
44862306a36Sopenharmony_ci    struct wf_sample_offset sampleEndOffset;
44962306a36Sopenharmony_ci    struct wf_sample_offset loopEndOffset;
45062306a36Sopenharmony_ci
45162306a36Sopenharmony_ci    s16  FrequencyBias;
45262306a36Sopenharmony_ci
45362306a36Sopenharmony_ci    u8 SampleResolution:2;
45462306a36Sopenharmony_ci    u8 Unused1:1;
45562306a36Sopenharmony_ci    u8 Loop:1;
45662306a36Sopenharmony_ci    u8 Bidirectional:1;
45762306a36Sopenharmony_ci    u8 Unused2:1;
45862306a36Sopenharmony_ci    u8 Reverse:1;
45962306a36Sopenharmony_ci    u8 Unused3:1;
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_ci    /* This structure is meant to be padded only to 16 bits on their
46262306a36Sopenharmony_ci       original. Of course, whoever wrote their documentation didn't
46362306a36Sopenharmony_ci       realize that sizeof(struct) can be >=
46462306a36Sopenharmony_ci       sum(sizeof(struct-fields)) and so thought that giving a C level
46562306a36Sopenharmony_ci       description of the structs used in WavePatch files was
46662306a36Sopenharmony_ci       sufficient. I suppose it was, as long as you remember the
46762306a36Sopenharmony_ci       standard 16->32 bit issues.
46862306a36Sopenharmony_ci    */
46962306a36Sopenharmony_ci
47062306a36Sopenharmony_ci    u8 sixteen_bit_padding;
47162306a36Sopenharmony_ci} __attribute__((packed)) wavefront_alias;
47262306a36Sopenharmony_ci
47362306a36Sopenharmony_citypedef struct wf_drum {
47462306a36Sopenharmony_ci    u8 PatchNumber;
47562306a36Sopenharmony_ci    u8 MixLevel:7;
47662306a36Sopenharmony_ci    u8 Unmute:1;
47762306a36Sopenharmony_ci    u8 Group:4;
47862306a36Sopenharmony_ci    u8 Unused1:4;
47962306a36Sopenharmony_ci    u8 PanModSource:2;
48062306a36Sopenharmony_ci    u8 PanModulated:1;
48162306a36Sopenharmony_ci    u8 PanAmount:4;
48262306a36Sopenharmony_ci    u8 Unused2:1;
48362306a36Sopenharmony_ci} wavefront_drum;
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_citypedef struct wf_drumkit {
48662306a36Sopenharmony_ci    struct wf_drum drum[NUM_MIDIKEYS];
48762306a36Sopenharmony_ci} wavefront_drumkit;
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_citypedef struct wf_channel_programs {
49062306a36Sopenharmony_ci    u8 Program[NUM_MIDICHANNELS];
49162306a36Sopenharmony_ci} wavefront_channel_programs;
49262306a36Sopenharmony_ci
49362306a36Sopenharmony_ci/* How to get MIDI channel status from the data returned by
49462306a36Sopenharmony_ci   a WFC_GET_CHANNEL_STATUS command (a struct wf_channel_programs)
49562306a36Sopenharmony_ci*/
49662306a36Sopenharmony_ci
49762306a36Sopenharmony_ci#define WF_CHANNEL_STATUS(ch,wcp) (wcp)[(ch/7)] & (1<<((ch)%7))
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_citypedef union wf_any {
50062306a36Sopenharmony_ci    wavefront_sample s;
50162306a36Sopenharmony_ci    wavefront_multisample ms;
50262306a36Sopenharmony_ci    wavefront_alias a;
50362306a36Sopenharmony_ci    wavefront_program pr;
50462306a36Sopenharmony_ci    wavefront_patch p;
50562306a36Sopenharmony_ci    wavefront_drum d;
50662306a36Sopenharmony_ci} wavefront_any;
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_ci/* Hannu Solvainen hoped that his "patch_info" struct in soundcard.h
50962306a36Sopenharmony_ci   might work for other wave-table based patch loading situations.
51062306a36Sopenharmony_ci   Alas, his fears were correct. The WaveFront doesn't even come with
51162306a36Sopenharmony_ci   just "patches", but several different kind of structures that
51262306a36Sopenharmony_ci   control the sound generation process.
51362306a36Sopenharmony_ci */
51462306a36Sopenharmony_ci
51562306a36Sopenharmony_citypedef struct wf_patch_info {
51662306a36Sopenharmony_ci
51762306a36Sopenharmony_ci    /* the first two fields are used by the OSS "patch loading" interface
51862306a36Sopenharmony_ci       only, and are unused by the current user-level library.
51962306a36Sopenharmony_ci    */
52062306a36Sopenharmony_ci
52162306a36Sopenharmony_ci    s16   key;               /* Use WAVEFRONT_PATCH here */
52262306a36Sopenharmony_ci    u16  devno;             /* fill in when sending */
52362306a36Sopenharmony_ci    u8  subkey;            /* WF_ST_{SAMPLE,ALIAS,etc.} */
52462306a36Sopenharmony_ci
52562306a36Sopenharmony_ci#define WAVEFRONT_FIND_FREE_SAMPLE_SLOT 999
52662306a36Sopenharmony_ci
52762306a36Sopenharmony_ci    u16  number;            /* patch/sample/prog number */
52862306a36Sopenharmony_ci
52962306a36Sopenharmony_ci    u32  size;              /* size of any data included in
53062306a36Sopenharmony_ci				  one of the fields in `hdrptr', or
53162306a36Sopenharmony_ci				  as `dataptr'.
53262306a36Sopenharmony_ci
53362306a36Sopenharmony_ci				  NOTE: for actual samples, this is
53462306a36Sopenharmony_ci				  the size of the *SELECTED CHANNEL*
53562306a36Sopenharmony_ci				  even if more data is actually available.
53662306a36Sopenharmony_ci
53762306a36Sopenharmony_ci				  So, a stereo sample (2 channels) of
53862306a36Sopenharmony_ci				  6000 bytes total has `size' = 3000.
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_ci				  See the macros and comments for
54162306a36Sopenharmony_ci				  WF_{GET,SET}_CHANNEL above.
54262306a36Sopenharmony_ci
54362306a36Sopenharmony_ci			       */
54462306a36Sopenharmony_ci    wavefront_any __user *hdrptr;      /* user-space ptr to hdr bytes */
54562306a36Sopenharmony_ci    u16 __user *dataptr;            /* actual sample data */
54662306a36Sopenharmony_ci
54762306a36Sopenharmony_ci    wavefront_any hdr;          /* kernel-space copy of hdr bytes */
54862306a36Sopenharmony_ci} wavefront_patch_info;
54962306a36Sopenharmony_ci
55062306a36Sopenharmony_ci/* The maximum number of bytes we will ever move to or from user space
55162306a36Sopenharmony_ci   in response to a WFC_* command.  This obviously doesn't cover
55262306a36Sopenharmony_ci   actual sample data.
55362306a36Sopenharmony_ci*/
55462306a36Sopenharmony_ci
55562306a36Sopenharmony_ci#define WF_MAX_READ sizeof(wavefront_multisample)
55662306a36Sopenharmony_ci#define WF_MAX_WRITE sizeof(wavefront_multisample)
55762306a36Sopenharmony_ci
55862306a36Sopenharmony_ci/*
55962306a36Sopenharmony_ci   This allows us to execute any WF command except the download/upload
56062306a36Sopenharmony_ci   ones, which are handled differently due to copyin/copyout issues as
56162306a36Sopenharmony_ci   well as data-nybbling to/from the card.
56262306a36Sopenharmony_ci */
56362306a36Sopenharmony_ci
56462306a36Sopenharmony_citypedef struct wavefront_control {
56562306a36Sopenharmony_ci    int cmd;                           /* WFC_* */
56662306a36Sopenharmony_ci    char status;                       /* return status to user-space */
56762306a36Sopenharmony_ci    unsigned char rbuf[WF_MAX_READ];   /* bytes read from card */
56862306a36Sopenharmony_ci    unsigned char wbuf[WF_MAX_WRITE];  /* bytes written to card */
56962306a36Sopenharmony_ci} wavefront_control;
57062306a36Sopenharmony_ci
57162306a36Sopenharmony_ci#define WFCTL_WFCMD    0x1
57262306a36Sopenharmony_ci#define WFCTL_LOAD_SPP 0x2
57362306a36Sopenharmony_ci
57462306a36Sopenharmony_ci/* Modulator table */
57562306a36Sopenharmony_ci
57662306a36Sopenharmony_ci#define WF_MOD_LFO1      0
57762306a36Sopenharmony_ci#define WF_MOD_LFO2      1
57862306a36Sopenharmony_ci#define WF_MOD_ENV1      2
57962306a36Sopenharmony_ci#define WF_MOD_ENV2      3
58062306a36Sopenharmony_ci#define WF_MOD_KEYBOARD  4
58162306a36Sopenharmony_ci#define WF_MOD_LOGKEY    5
58262306a36Sopenharmony_ci#define WF_MOD_VELOCITY  6
58362306a36Sopenharmony_ci#define WF_MOD_LOGVEL    7
58462306a36Sopenharmony_ci#define WF_MOD_RANDOM    8
58562306a36Sopenharmony_ci#define WF_MOD_PRESSURE  9
58662306a36Sopenharmony_ci#define WF_MOD_MOD_WHEEL 10
58762306a36Sopenharmony_ci#define WF_MOD_1         WF_MOD_MOD_WHEEL
58862306a36Sopenharmony_ci#define WF_MOD_BREATH    11
58962306a36Sopenharmony_ci#define WF_MOD_2         WF_MOD_BREATH
59062306a36Sopenharmony_ci#define WF_MOD_FOOT      12
59162306a36Sopenharmony_ci#define WF_MOD_4         WF_MOD_FOOT
59262306a36Sopenharmony_ci#define WF_MOD_VOLUME    13
59362306a36Sopenharmony_ci#define WF_MOD_7         WF_MOD_VOLUME
59462306a36Sopenharmony_ci#define WF_MOD_PAN       14
59562306a36Sopenharmony_ci#define WF_MOD_10        WF_MOD_PAN
59662306a36Sopenharmony_ci#define WF_MOD_EXPR      15
59762306a36Sopenharmony_ci#define WF_MOD_11        WF_MOD_EXPR
59862306a36Sopenharmony_ci
59962306a36Sopenharmony_ci/* FX-related material */
60062306a36Sopenharmony_ci
60162306a36Sopenharmony_citypedef struct wf_fx_info {
60262306a36Sopenharmony_ci    int request;             /* see list below */
60362306a36Sopenharmony_ci    long data[4];             /* we don't need much */
60462306a36Sopenharmony_ci} wavefront_fx_info;
60562306a36Sopenharmony_ci
60662306a36Sopenharmony_ci/* support for each of these will be forthcoming once I or someone
60762306a36Sopenharmony_ci   else has figured out which of the addresses on page 6 and page 7 of
60862306a36Sopenharmony_ci   the YSS225 control each parameter. Incidentally, these come from
60962306a36Sopenharmony_ci   the Windows driver interface, but again, Turtle Beach didn't
61062306a36Sopenharmony_ci   document the API to use them.
61162306a36Sopenharmony_ci*/
61262306a36Sopenharmony_ci
61362306a36Sopenharmony_ci#define WFFX_SETOUTGAIN		        0
61462306a36Sopenharmony_ci#define WFFX_SETSTEREOOUTGAIN		1
61562306a36Sopenharmony_ci#define WFFX_SETREVERBIN1GAIN		2
61662306a36Sopenharmony_ci#define WFFX_SETREVERBIN2GAIN		3
61762306a36Sopenharmony_ci#define WFFX_SETREVERBIN3GAIN		4
61862306a36Sopenharmony_ci#define WFFX_SETCHORUSINPORT		5
61962306a36Sopenharmony_ci#define WFFX_SETREVERBIN1PORT		6
62062306a36Sopenharmony_ci#define WFFX_SETREVERBIN2PORT		7
62162306a36Sopenharmony_ci#define WFFX_SETREVERBIN3PORT		8
62262306a36Sopenharmony_ci#define WFFX_SETEFFECTPORT		9
62362306a36Sopenharmony_ci#define WFFX_SETAUXPORT		        10
62462306a36Sopenharmony_ci#define WFFX_SETREVERBTYPE		11
62562306a36Sopenharmony_ci#define WFFX_SETREVERBDELAY		12
62662306a36Sopenharmony_ci#define WFFX_SETCHORUSLFO		13
62762306a36Sopenharmony_ci#define WFFX_SETCHORUSPMD		14
62862306a36Sopenharmony_ci#define WFFX_SETCHORUSAMD		15
62962306a36Sopenharmony_ci#define WFFX_SETEFFECT		        16
63062306a36Sopenharmony_ci#define WFFX_SETBASEALL		        17
63162306a36Sopenharmony_ci#define WFFX_SETREVERBALL		18
63262306a36Sopenharmony_ci#define WFFX_SETCHORUSALL		20
63362306a36Sopenharmony_ci#define WFFX_SETREVERBDEF		22
63462306a36Sopenharmony_ci#define WFFX_SETCHORUSDEF		23
63562306a36Sopenharmony_ci#define WFFX_DELAYSETINGAIN		24
63662306a36Sopenharmony_ci#define WFFX_DELAYSETFBGAIN	        25
63762306a36Sopenharmony_ci#define WFFX_DELAYSETFBLPF		26
63862306a36Sopenharmony_ci#define WFFX_DELAYSETGAIN		27
63962306a36Sopenharmony_ci#define WFFX_DELAYSETTIME		28
64062306a36Sopenharmony_ci#define WFFX_DELAYSETFBTIME		29
64162306a36Sopenharmony_ci#define WFFX_DELAYSETALL		30
64262306a36Sopenharmony_ci#define WFFX_DELAYSETDEF		32
64362306a36Sopenharmony_ci#define WFFX_SDELAYSETINGAIN		33
64462306a36Sopenharmony_ci#define WFFX_SDELAYSETFBGAIN		34
64562306a36Sopenharmony_ci#define WFFX_SDELAYSETFBLPF		35
64662306a36Sopenharmony_ci#define WFFX_SDELAYSETGAIN		36
64762306a36Sopenharmony_ci#define WFFX_SDELAYSETTIME		37
64862306a36Sopenharmony_ci#define WFFX_SDELAYSETFBTIME		38
64962306a36Sopenharmony_ci#define WFFX_SDELAYSETALL		39
65062306a36Sopenharmony_ci#define WFFX_SDELAYSETDEF		41
65162306a36Sopenharmony_ci#define WFFX_DEQSETINGAIN		42
65262306a36Sopenharmony_ci#define WFFX_DEQSETFILTER		43
65362306a36Sopenharmony_ci#define WFFX_DEQSETALL		        44
65462306a36Sopenharmony_ci#define WFFX_DEQSETDEF		        46
65562306a36Sopenharmony_ci#define WFFX_MUTE		        47
65662306a36Sopenharmony_ci#define WFFX_FLANGESETBALANCE	        48
65762306a36Sopenharmony_ci#define WFFX_FLANGESETDELAY		49
65862306a36Sopenharmony_ci#define WFFX_FLANGESETDWFFX_TH		50
65962306a36Sopenharmony_ci#define WFFX_FLANGESETFBGAIN		51
66062306a36Sopenharmony_ci#define WFFX_FLANGESETINGAIN		52
66162306a36Sopenharmony_ci#define WFFX_FLANGESETLFO		53
66262306a36Sopenharmony_ci#define WFFX_FLANGESETALL		54
66362306a36Sopenharmony_ci#define WFFX_FLANGESETDEF		56
66462306a36Sopenharmony_ci#define WFFX_PITCHSETSHIFT		57
66562306a36Sopenharmony_ci#define WFFX_PITCHSETBALANCE		58
66662306a36Sopenharmony_ci#define WFFX_PITCHSETALL		59
66762306a36Sopenharmony_ci#define WFFX_PITCHSETDEF		61
66862306a36Sopenharmony_ci#define WFFX_SRSSETINGAIN		62
66962306a36Sopenharmony_ci#define WFFX_SRSSETSPACE		63
67062306a36Sopenharmony_ci#define WFFX_SRSSETCENTER		64
67162306a36Sopenharmony_ci#define WFFX_SRSSETGAIN		        65
67262306a36Sopenharmony_ci#define WFFX_SRSSETMODE	        	66
67362306a36Sopenharmony_ci#define WFFX_SRSSETDEF		        68
67462306a36Sopenharmony_ci
67562306a36Sopenharmony_ci/* Allow direct user-space control over FX memory/coefficient data.
67662306a36Sopenharmony_ci   In theory this could be used to download the FX microprogram,
67762306a36Sopenharmony_ci   but it would be a little slower, and involve some weird code.
67862306a36Sopenharmony_ci */
67962306a36Sopenharmony_ci
68062306a36Sopenharmony_ci#define WFFX_MEMSET              69
68162306a36Sopenharmony_ci
68262306a36Sopenharmony_ci#endif /* __SOUND_WAVEFRONT_H__ */
683