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