Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
sound
synth
emux
emux_nrpn.c
Go to the documentation of this file.
1
/*
2
* NRPN / SYSEX callbacks for Emu8k/Emu10k1
3
*
4
* Copyright (c) 1999-2000 Takashi Iwai <
[email protected]
>
5
*
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
10
*
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
15
*
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
*
20
*/
21
22
#include "
emux_voice.h
"
23
#include <
sound/asoundef.h
>
24
25
/*
26
* conversion from NRPN/control parameters to Emu8000 raw parameters
27
*/
28
29
/* NRPN / CC -> Emu8000 parameter converter */
30
struct
nrpn_conv_table
{
31
int
control
;
32
int
effect
;
33
int
(*
convert
)(
int
val
);
34
};
35
36
/* effect sensitivity */
37
38
#define FX_CUTOFF 0
39
#define FX_RESONANCE 1
40
#define FX_ATTACK 2
41
#define FX_RELEASE 3
42
#define FX_VIBRATE 4
43
#define FX_VIBDEPTH 5
44
#define FX_VIBDELAY 6
45
#define FX_NUMS 7
46
47
/*
48
* convert NRPN/control values
49
*/
50
51
static
int
send_converted_effect(
struct
nrpn_conv_table
*
table
,
int
num_tables,
52
struct
snd_emux_port
*
port
,
53
struct
snd_midi_channel
*
chan
,
54
int
type
,
int
val
,
int
mode
)
55
{
56
int
i
, cval;
57
for
(i = 0; i < num_tables; i++) {
58
if
(table[i].
control
== type) {
59
cval = table[
i
].
convert
(val);
60
snd_emux_send_effect(port, chan, table[i].effect,
61
cval, mode);
62
return
1;
63
}
64
}
65
return
0;
66
}
67
68
#define DEF_FX_CUTOFF 170
69
#define DEF_FX_RESONANCE 6
70
#define DEF_FX_ATTACK 50
71
#define DEF_FX_RELEASE 50
72
#define DEF_FX_VIBRATE 30
73
#define DEF_FX_VIBDEPTH 4
74
#define DEF_FX_VIBDELAY 1500
75
76
/* effect sensitivities for GS NRPN:
77
* adjusted for chaos 8MB soundfonts
78
*/
79
static
int
gs_sense[] =
80
{
81
DEF_FX_CUTOFF
,
DEF_FX_RESONANCE
,
DEF_FX_ATTACK
,
DEF_FX_RELEASE
,
82
DEF_FX_VIBRATE
,
DEF_FX_VIBDEPTH
,
DEF_FX_VIBDELAY
83
};
84
85
/* effect sensitivies for XG controls:
86
* adjusted for chaos 8MB soundfonts
87
*/
88
static
int
xg_sense[] =
89
{
90
DEF_FX_CUTOFF
,
DEF_FX_RESONANCE
,
DEF_FX_ATTACK
,
DEF_FX_RELEASE
,
91
DEF_FX_VIBRATE
,
DEF_FX_VIBDEPTH
,
DEF_FX_VIBDELAY
92
};
93
94
95
/*
96
* AWE32 NRPN effects
97
*/
98
99
static
int
fx_delay(
int
val
);
100
static
int
fx_attack(
int
val
);
101
static
int
fx_hold(
int
val
);
102
static
int
fx_decay(
int
val
);
103
static
int
fx_the_value(
int
val
);
104
static
int
fx_twice_value(
int
val
);
105
static
int
fx_conv_pitch(
int
val
);
106
static
int
fx_conv_Q(
int
val
);
107
108
/* function for each NRPN */
/* [range] units */
109
#define fx_env1_delay fx_delay
/* [0,5900] 4msec */
110
#define fx_env1_attack fx_attack
/* [0,5940] 1msec */
111
#define fx_env1_hold fx_hold
/* [0,8191] 1msec */
112
#define fx_env1_decay fx_decay
/* [0,5940] 4msec */
113
#define fx_env1_release fx_decay
/* [0,5940] 4msec */
114
#define fx_env1_sustain fx_the_value
/* [0,127] 0.75dB */
115
#define fx_env1_pitch fx_the_value
/* [-127,127] 9.375cents */
116
#define fx_env1_cutoff fx_the_value
/* [-127,127] 56.25cents */
117
118
#define fx_env2_delay fx_delay
/* [0,5900] 4msec */
119
#define fx_env2_attack fx_attack
/* [0,5940] 1msec */
120
#define fx_env2_hold fx_hold
/* [0,8191] 1msec */
121
#define fx_env2_decay fx_decay
/* [0,5940] 4msec */
122
#define fx_env2_release fx_decay
/* [0,5940] 4msec */
123
#define fx_env2_sustain fx_the_value
/* [0,127] 0.75dB */
124
125
#define fx_lfo1_delay fx_delay
/* [0,5900] 4msec */
126
#define fx_lfo1_freq fx_twice_value
/* [0,127] 84mHz */
127
#define fx_lfo1_volume fx_twice_value
/* [0,127] 0.1875dB */
128
#define fx_lfo1_pitch fx_the_value
/* [-127,127] 9.375cents */
129
#define fx_lfo1_cutoff fx_twice_value
/* [-64,63] 56.25cents */
130
131
#define fx_lfo2_delay fx_delay
/* [0,5900] 4msec */
132
#define fx_lfo2_freq fx_twice_value
/* [0,127] 84mHz */
133
#define fx_lfo2_pitch fx_the_value
/* [-127,127] 9.375cents */
134
135
#define fx_init_pitch fx_conv_pitch
/* [-8192,8192] cents */
136
#define fx_chorus fx_the_value
/* [0,255] -- */
137
#define fx_reverb fx_the_value
/* [0,255] -- */
138
#define fx_cutoff fx_twice_value
/* [0,127] 62Hz */
139
#define fx_filterQ fx_conv_Q
/* [0,127] -- */
140
141
static
int
fx_delay(
int
val
)
142
{
143
return
(
unsigned
short
)
snd_sf_calc_parm_delay
(val);
144
}
145
146
static
int
fx_attack(
int
val
)
147
{
148
return
(
unsigned
short
)
snd_sf_calc_parm_attack
(val);
149
}
150
151
static
int
fx_hold(
int
val)
152
{
153
return
(
unsigned
short
)
snd_sf_calc_parm_hold
(val);
154
}
155
156
static
int
fx_decay(
int
val)
157
{
158
return
(
unsigned
short
)
snd_sf_calc_parm_decay
(val);
159
}
160
161
static
int
fx_the_value(
int
val)
162
{
163
return
(
unsigned
short
)(val & 0xff);
164
}
165
166
static
int
fx_twice_value(
int
val)
167
{
168
return
(
unsigned
short
)((val * 2) & 0xff);
169
}
170
171
static
int
fx_conv_pitch(
int
val)
172
{
173
return
(
short
)(val * 4096 / 1200);
174
}
175
176
static
int
fx_conv_Q(
int
val)
177
{
178
return
(
unsigned
short
)((val / 8) & 0xff);
179
}
180
181
182
static
struct
nrpn_conv_table
awe_effects[] =
183
{
184
{ 0,
EMUX_FX_LFO1_DELAY
,
fx_lfo1_delay
},
185
{ 1,
EMUX_FX_LFO1_FREQ
,
fx_lfo1_freq
},
186
{ 2,
EMUX_FX_LFO2_DELAY
,
fx_lfo2_delay
},
187
{ 3,
EMUX_FX_LFO2_FREQ
,
fx_lfo2_freq
},
188
189
{ 4,
EMUX_FX_ENV1_DELAY
,
fx_env1_delay
},
190
{ 5,
EMUX_FX_ENV1_ATTACK
,
fx_env1_attack
},
191
{ 6,
EMUX_FX_ENV1_HOLD
,
fx_env1_hold
},
192
{ 7,
EMUX_FX_ENV1_DECAY
,
fx_env1_decay
},
193
{ 8,
EMUX_FX_ENV1_SUSTAIN
,
fx_env1_sustain
},
194
{ 9,
EMUX_FX_ENV1_RELEASE
,
fx_env1_release
},
195
196
{10,
EMUX_FX_ENV2_DELAY
,
fx_env2_delay
},
197
{11,
EMUX_FX_ENV2_ATTACK
,
fx_env2_attack
},
198
{12,
EMUX_FX_ENV2_HOLD
,
fx_env2_hold
},
199
{13,
EMUX_FX_ENV2_DECAY
,
fx_env2_decay
},
200
{14,
EMUX_FX_ENV2_SUSTAIN
,
fx_env2_sustain
},
201
{15,
EMUX_FX_ENV2_RELEASE
,
fx_env2_release
},
202
203
{16,
EMUX_FX_INIT_PITCH
,
fx_init_pitch
},
204
{17,
EMUX_FX_LFO1_PITCH
,
fx_lfo1_pitch
},
205
{18,
EMUX_FX_LFO2_PITCH
,
fx_lfo2_pitch
},
206
{19,
EMUX_FX_ENV1_PITCH
,
fx_env1_pitch
},
207
{20,
EMUX_FX_LFO1_VOLUME
,
fx_lfo1_volume
},
208
{21,
EMUX_FX_CUTOFF
,
fx_cutoff
},
209
{22,
EMUX_FX_FILTERQ
,
fx_filterQ
},
210
{23,
EMUX_FX_LFO1_CUTOFF
,
fx_lfo1_cutoff
},
211
{24,
EMUX_FX_ENV1_CUTOFF
,
fx_env1_cutoff
},
212
{25,
EMUX_FX_CHORUS
,
fx_chorus
},
213
{26,
EMUX_FX_REVERB
,
fx_reverb
},
214
};
215
216
217
/*
218
* GS(SC88) NRPN effects; still experimental
219
*/
220
221
/* cutoff: quarter semitone step, max=255 */
222
static
int
gs_cutoff(
int
val)
223
{
224
return
(val - 64) * gs_sense[
FX_CUTOFF
] / 50;
225
}
226
227
/* resonance: 0 to 15(max) */
228
static
int
gs_filterQ(
int
val)
229
{
230
return
(val - 64) * gs_sense[
FX_RESONANCE
] / 50;
231
}
232
233
/* attack: */
234
static
int
gs_attack(
int
val)
235
{
236
return
-(val - 64) * gs_sense[
FX_ATTACK
] / 50;
237
}
238
239
/* decay: */
240
static
int
gs_decay(
int
val)
241
{
242
return
-(val - 64) * gs_sense[
FX_RELEASE
] / 50;
243
}
244
245
/* release: */
246
static
int
gs_release(
int
val)
247
{
248
return
-(val - 64) * gs_sense[
FX_RELEASE
] / 50;
249
}
250
251
/* vibrato freq: 0.042Hz step, max=255 */
252
static
int
gs_vib_rate(
int
val)
253
{
254
return
(val - 64) * gs_sense[
FX_VIBRATE
] / 50;
255
}
256
257
/* vibrato depth: max=127, 1 octave */
258
static
int
gs_vib_depth(
int
val)
259
{
260
return
(val - 64) * gs_sense[
FX_VIBDEPTH
] / 50;
261
}
262
263
/* vibrato delay: -0.725msec step */
264
static
int
gs_vib_delay(
int
val)
265
{
266
return
-(val - 64) * gs_sense[
FX_VIBDELAY
] / 50;
267
}
268
269
static
struct
nrpn_conv_table
gs_effects[] =
270
{
271
{32,
EMUX_FX_CUTOFF
, gs_cutoff},
272
{33,
EMUX_FX_FILTERQ
, gs_filterQ},
273
{99,
EMUX_FX_ENV2_ATTACK
, gs_attack},
274
{100,
EMUX_FX_ENV2_DECAY
, gs_decay},
275
{102,
EMUX_FX_ENV2_RELEASE
, gs_release},
276
{8,
EMUX_FX_LFO1_FREQ
, gs_vib_rate},
277
{9,
EMUX_FX_LFO1_VOLUME
, gs_vib_depth},
278
{10,
EMUX_FX_LFO1_DELAY
, gs_vib_delay},
279
};
280
281
282
/*
283
* NRPN events
284
*/
285
void
286
snd_emux_nrpn
(
void
*
p
,
struct
snd_midi_channel
*
chan
,
287
struct
snd_midi_channel_set
*chset)
288
{
289
struct
snd_emux_port
*
port
;
290
291
port =
p
;
292
if
(
snd_BUG_ON
(!port || !chan))
293
return
;
294
295
if
(chan->
control
[
MIDI_CTL_NONREG_PARM_NUM_MSB
] == 127 &&
296
chan->
control
[
MIDI_CTL_NONREG_PARM_NUM_LSB
] <= 26) {
297
int
val
;
298
/* Win/DOS AWE32 specific NRPNs */
299
/* both MSB/LSB necessary */
300
val = (chan->
control
[
MIDI_CTL_MSB_DATA_ENTRY
] << 7) |
301
chan->
control
[
MIDI_CTL_LSB_DATA_ENTRY
];
302
val -= 8192;
303
send_converted_effect
304
(awe_effects,
ARRAY_SIZE
(awe_effects),
305
port
, chan, chan->control[
MIDI_CTL_NONREG_PARM_NUM_LSB
],
306
val
,
EMUX_FX_FLAG_SET
);
307
return
;
308
}
309
310
if
(port->
chset
.midi_mode ==
SNDRV_MIDI_MODE_GS
&&
311
chan->
control
[
MIDI_CTL_NONREG_PARM_NUM_MSB
] == 1) {
312
int
val
;
313
/* GS specific NRPNs */
314
/* only MSB is valid */
315
val = chan->
control
[
MIDI_CTL_MSB_DATA_ENTRY
];
316
send_converted_effect
317
(gs_effects,
ARRAY_SIZE
(gs_effects),
318
port, chan, chan->
control
[
MIDI_CTL_NONREG_PARM_NUM_LSB
],
319
val,
EMUX_FX_FLAG_ADD
);
320
return
;
321
}
322
}
323
324
325
/*
326
* XG control effects; still experimental
327
*/
328
329
/* cutoff: quarter semitone step, max=255 */
330
static
int
xg_cutoff(
int
val)
331
{
332
return
(val - 64) * xg_sense[
FX_CUTOFF
] / 64;
333
}
334
335
/* resonance: 0(open) to 15(most nasal) */
336
static
int
xg_filterQ(
int
val)
337
{
338
return
(val - 64) * xg_sense[
FX_RESONANCE
] / 64;
339
}
340
341
/* attack: */
342
static
int
xg_attack(
int
val)
343
{
344
return
-(val - 64) * xg_sense[
FX_ATTACK
] / 64;
345
}
346
347
/* release: */
348
static
int
xg_release(
int
val)
349
{
350
return
-(val - 64) * xg_sense[
FX_RELEASE
] / 64;
351
}
352
353
static
struct
nrpn_conv_table
xg_effects[] =
354
{
355
{71,
EMUX_FX_CUTOFF
, xg_cutoff},
356
{74,
EMUX_FX_FILTERQ
, xg_filterQ},
357
{72,
EMUX_FX_ENV2_RELEASE
, xg_release},
358
{73,
EMUX_FX_ENV2_ATTACK
, xg_attack},
359
};
360
361
int
362
snd_emux_xg_control
(
struct
snd_emux_port
*
port
,
struct
snd_midi_channel
*
chan
,
363
int
param
)
364
{
365
return
send_converted_effect(xg_effects,
ARRAY_SIZE
(xg_effects),
366
port, chan, param,
367
chan->
control
[param],
368
EMUX_FX_FLAG_ADD
);
369
}
370
371
/*
372
* receive sysex
373
*/
374
void
375
snd_emux_sysex
(
void
*
p
,
unsigned
char
*
buf
,
int
len,
int
parsed,
376
struct
snd_midi_channel_set
*chset)
377
{
378
struct
snd_emux_port
*
port
;
379
struct
snd_emux
*
emu
;
380
381
port =
p
;
382
if
(
snd_BUG_ON
(!port || !chset))
383
return
;
384
emu = port->
emu
;
385
386
switch
(parsed) {
387
case
SNDRV_MIDI_SYSEX_GS_MASTER_VOLUME
:
388
snd_emux_update_port
(port,
SNDRV_EMUX_UPDATE_VOLUME
);
389
break
;
390
default
:
391
if
(emu->
ops
.sysex)
392
emu->
ops
.sysex(emu, buf, len, parsed, chset);
393
break
;
394
}
395
}
396
Generated on Thu Jan 10 2013 15:08:50 for Linux Kernel by
1.8.2