dfed85b58b3a2d77abdcb6d111905633e0868f7d
[linux-2.6.git] / sound / isa / gus / gus_simple.c
1 /*
2  *  Routines for Gravis UltraSound soundcards - Simple instrument handlers
3  *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
4  *
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 <sound/driver.h>
23 #include <linux/time.h>
24 #include <sound/core.h>
25 #include <sound/gus.h>
26 #include "gus_tables.h"
27
28 /*
29  *
30  */
31
32 static void interrupt_wave(snd_gus_card_t *gus, snd_gus_voice_t *voice);
33 static void interrupt_volume(snd_gus_card_t *gus, snd_gus_voice_t *voice);
34 static void interrupt_effect(snd_gus_card_t *gus, snd_gus_voice_t *voice);
35
36 static void sample_start(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_position_t position);
37 static void sample_stop(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_stop_mode_t mode);
38 static void sample_freq(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_frequency_t freq);
39 static void sample_volume(snd_gus_card_t *card, snd_gus_voice_t *voice, snd_seq_ev_volume_t *volume);
40 static void sample_loop(snd_gus_card_t *card, snd_gus_voice_t *voice, snd_seq_ev_loop_t *loop);
41 static void sample_pos(snd_gus_card_t *card, snd_gus_voice_t *voice, snd_seq_position_t position);
42 static void sample_private1(snd_gus_card_t *card, snd_gus_voice_t *voice, unsigned char *data);
43
44 static snd_gus_sample_ops_t sample_ops = {
45         sample_start,
46         sample_stop,
47         sample_freq,
48         sample_volume,
49         sample_loop,
50         sample_pos,
51         sample_private1
52 };
53
54 #if 0
55
56 static void note_stop(snd_gus_card_t *gus, snd_gus_voice_t *voice, int wait);
57 static void note_wait(snd_gus_card_t *gus, snd_gus_voice_t *voice);
58 static void note_off(snd_gus_card_t *gus, snd_gus_voice_t *voice);
59 static void note_volume(snd_gus_card_t *card, snd_gus_voice_t *voice);
60 static void note_pitchbend(snd_gus_card_t *card, snd_gus_voice_t *voice);
61 static void note_vibrato(snd_gus_card_t *card, snd_gus_voice_t *voice);
62 static void note_tremolo(snd_gus_card_t *card, snd_gus_voice_t *voice);
63
64 static struct snd_gus_note_handlers note_commands = {
65         note_stop,
66         note_wait,
67         note_off,
68         note_volume,
69         note_pitchbend,
70         note_vibrato,
71         note_tremolo
72 };
73
74 static void chn_trigger_down(snd_gus_card_t *card, ultra_channel_t *channel, ultra_instrument_t *instrument, unsigned char note, unsigned char velocity, unsigned char priority );
75 static void chn_trigger_up( ultra_card_t *card, ultra_note_t *note );
76 static void chn_control( ultra_card_t *card, ultra_channel_t *channel, unsigned short p1, unsigned short p2 );
77
78 static struct ULTRA_STRU_INSTRUMENT_CHANNEL_COMMANDS channel_commands = {
79   chn_trigger_down,
80   chn_trigger_up,
81   chn_control
82 };
83
84 #endif
85
86 static void do_volume_envelope(snd_gus_card_t *card, snd_gus_voice_t *voice);
87 static void do_pan_envelope(snd_gus_card_t *card, snd_gus_voice_t *voice);
88
89 /*
90  *
91  */
92
93 static void interrupt_wave(snd_gus_card_t *gus, snd_gus_voice_t *voice)
94 {
95         spin_lock(&gus->event_lock);
96         snd_gf1_stop_voice(gus, voice->number);
97         spin_lock(&gus->reg_lock);
98         snd_gf1_select_voice(gus, voice->number);
99         snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, 0);
100         spin_unlock(&gus->reg_lock);
101         voice->flags &= ~SNDRV_GF1_VFLG_RUNNING;
102         spin_unlock(&gus->event_lock);
103 }
104
105 static void interrupt_volume(snd_gus_card_t *gus, snd_gus_voice_t *voice)
106 {
107         spin_lock(&gus->event_lock);
108         if (voice->flags & SNDRV_GF1_VFLG_RUNNING)
109                 do_volume_envelope(gus, voice);
110         else
111                 snd_gf1_stop_voice(gus, voice->number);
112         spin_unlock(&gus->event_lock);
113 }
114
115 static void interrupt_effect(snd_gus_card_t *gus, snd_gus_voice_t *voice)
116 {
117         spin_lock(&gus->event_lock);
118         if ((voice->flags & (SNDRV_GF1_VFLG_RUNNING|SNDRV_GF1_VFLG_EFFECT_TIMER1)) ==
119                             (SNDRV_GF1_VFLG_RUNNING|SNDRV_GF1_VFLG_EFFECT_TIMER1))
120                 do_pan_envelope(gus, voice);
121         spin_unlock(&gus->event_lock);
122 }
123
124 /*
125  *
126  */
127
128 static void do_volume_envelope(snd_gus_card_t *gus, snd_gus_voice_t *voice)
129 {
130         unsigned short next, rate, old_volume;
131         int program_next_ramp;
132         unsigned long flags;
133   
134         if (!gus->gf1.volume_ramp) {
135                 spin_lock_irqsave(&gus->reg_lock, flags);
136                 snd_gf1_select_voice(gus, voice->number);
137                 snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
138                 snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, voice->gf1_volume);
139                 /* printk("gf1_volume = 0x%x\n", voice->gf1_volume); */
140                 spin_unlock_irqrestore(&gus->reg_lock, flags);
141                 return;
142         }
143         program_next_ramp = 0;
144         rate = next = 0;
145         while (1) {
146                 program_next_ramp = 0;
147                 rate = next = 0;
148                 switch (voice->venv_state) {
149                 case VENV_BEFORE:
150                         voice->venv_state = VENV_ATTACK;
151                         voice->venv_value_next = 0;
152                         spin_lock_irqsave(&gus->reg_lock, flags);
153                         snd_gf1_select_voice(gus, voice->number);
154                         snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
155                         snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, SNDRV_GF1_MIN_VOLUME);
156                         spin_unlock_irqrestore(&gus->reg_lock, flags);
157                         break;
158                 case VENV_ATTACK:
159                         voice->venv_state = VENV_SUSTAIN;
160                         program_next_ramp++;
161                         next = 255;
162                         rate = gus->gf1.volume_ramp;
163                         break;
164                 case VENV_SUSTAIN:
165                         voice->venv_state = VENV_RELEASE;
166                         spin_lock_irqsave(&gus->reg_lock, flags);
167                         snd_gf1_select_voice(gus, voice->number);
168                         snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
169                         snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, ((int)voice->gf1_volume * (int)voice->venv_value_next) / 255);
170                         spin_unlock_irqrestore(&gus->reg_lock, flags);
171                         return;
172                 case VENV_RELEASE:
173                         voice->venv_state = VENV_DONE;
174                         program_next_ramp++;
175                         next = 0;
176                         rate = gus->gf1.volume_ramp;
177                         break;
178                 case VENV_DONE:
179                         snd_gf1_stop_voice(gus, voice->number);
180                         voice->flags &= ~SNDRV_GF1_VFLG_RUNNING;
181                         return;
182                 case VENV_VOLUME:
183                         program_next_ramp++;
184                         next = voice->venv_value_next;
185                         rate = gus->gf1.volume_ramp;
186                         voice->venv_state = voice->venv_state_prev;
187                         break;
188                 }
189                 voice->venv_value_next = next;
190                 if (!program_next_ramp)
191                         continue;
192                 spin_lock_irqsave(&gus->reg_lock, flags);
193                 snd_gf1_select_voice(gus, voice->number);
194                 snd_gf1_ctrl_stop(gus, SNDRV_GF1_VB_VOLUME_CONTROL);
195                 old_volume = snd_gf1_read16(gus, SNDRV_GF1_VW_VOLUME) >> 8;
196                 if (!rate) {
197                         spin_unlock_irqrestore(&gus->reg_lock, flags);                  
198                         continue;
199                 }
200                 next = (((int)voice->gf1_volume * (int)next) / 255) >> 8;
201                 if (old_volume < SNDRV_GF1_MIN_OFFSET)
202                         old_volume = SNDRV_GF1_MIN_OFFSET;
203                 if (next < SNDRV_GF1_MIN_OFFSET)
204                         next = SNDRV_GF1_MIN_OFFSET;
205                 if (next > SNDRV_GF1_MAX_OFFSET)
206                         next = SNDRV_GF1_MAX_OFFSET;
207                 if (old_volume == next) {
208                         spin_unlock_irqrestore(&gus->reg_lock, flags);
209                         continue;
210                 }
211                 voice->volume_control &= ~0xc3;
212                 voice->volume_control |= 0x20;
213                 if (old_volume > next) {
214                         snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_START, next);
215                         snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_END, old_volume);
216                         voice->volume_control |= 0x40;
217                 } else {
218                         snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_START, old_volume);
219                         snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_END, next);
220                 }
221                 snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_RATE, rate);
222                 snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_CONTROL, voice->volume_control);
223                 if (!gus->gf1.enh_mode) {
224                         snd_gf1_delay(gus);
225                         snd_gf1_write8(gus, SNDRV_GF1_VB_VOLUME_CONTROL, voice->volume_control);
226                 }
227                 spin_unlock_irqrestore(&gus->reg_lock, flags);                  
228                 return;
229         }
230 }
231
232 static void do_pan_envelope(snd_gus_card_t *gus, snd_gus_voice_t *voice)
233 {
234         unsigned long flags;
235         unsigned char old_pan;
236
237 #if 0
238         snd_gf1_select_voice(gus, voice->number);
239         printk(" -%i- do_pan_envelope - flags = 0x%x (0x%x -> 0x%x)\n",
240                 voice->number,
241                 voice->flags,
242                 voice->gf1_pan,
243                 snd_gf1_i_read8(gus, SNDRV_GF1_VB_PAN) & 0x0f);
244 #endif
245         if (gus->gf1.enh_mode) {
246                 voice->flags &= ~(SNDRV_GF1_VFLG_EFFECT_TIMER1|SNDRV_GF1_VFLG_PAN);
247                 return;
248         }
249         if (!gus->gf1.smooth_pan) {
250                 spin_lock_irqsave(&gus->reg_lock, flags);                       
251                 snd_gf1_select_voice(gus, voice->number);
252                 snd_gf1_write8(gus, SNDRV_GF1_VB_PAN, voice->gf1_pan);
253                 spin_unlock_irqrestore(&gus->reg_lock, flags);
254                 return;
255         }
256         if (!(voice->flags & SNDRV_GF1_VFLG_PAN))               /* before */
257                 voice->flags |= SNDRV_GF1_VFLG_EFFECT_TIMER1|SNDRV_GF1_VFLG_PAN;
258         spin_lock_irqsave(&gus->reg_lock, flags);                       
259         snd_gf1_select_voice(gus, voice->number);
260         old_pan = snd_gf1_read8(gus, SNDRV_GF1_VB_PAN) & 0x0f;
261         if (old_pan > voice->gf1_pan )
262                 old_pan--;
263         if (old_pan < voice->gf1_pan)
264                 old_pan++;
265         snd_gf1_write8(gus, SNDRV_GF1_VB_PAN, old_pan);
266         spin_unlock_irqrestore(&gus->reg_lock, flags);
267         if (old_pan == voice->gf1_pan)                  /* the goal was reached */
268                 voice->flags &= ~(SNDRV_GF1_VFLG_EFFECT_TIMER1|SNDRV_GF1_VFLG_PAN);
269 #if 0
270         snd_gf1_select_voice(gus, voice->number);
271         printk(" -%i- (1) do_pan_envelope - flags = 0x%x (0x%x -> 0x%x)\n",
272                voice->number,
273                voice->flags,
274                voice->gf1_pan,
275                snd_gf1_i_read8(gus, GF1_VB_PAN) & 0x0f);
276 #endif
277 }
278
279 static void set_enhanced_pan(snd_gus_card_t *gus, snd_gus_voice_t *voice, unsigned short pan)
280 {
281         unsigned long flags;
282         unsigned short vlo, vro;
283   
284         vlo = SNDRV_GF1_ATTEN((SNDRV_GF1_ATTEN_TABLE_SIZE-1) - pan);
285         vro = SNDRV_GF1_ATTEN(pan);
286         if (pan != SNDRV_GF1_ATTEN_TABLE_SIZE - 1 && pan != 0) {
287                 vlo >>= 1;
288                 vro >>= 1;
289         }
290         vlo <<= 4;
291         vro <<= 4;
292 #if 0
293         printk("vlo = 0x%x (0x%x), vro = 0x%x (0x%x)\n",
294                         vlo, snd_gf1_i_read16(gus, GF1_VW_OFFSET_LEFT),
295                         vro, snd_gf1_i_read16(gus, GF1_VW_OFFSET_RIGHT));
296 #endif
297         spin_lock_irqsave(&gus->reg_lock, flags);                       
298         snd_gf1_select_voice(gus, voice->number);
299         snd_gf1_write16(gus, SNDRV_GF1_VW_OFFSET_LEFT_FINAL, vlo);
300         snd_gf1_write16(gus, SNDRV_GF1_VW_OFFSET_RIGHT_FINAL, vro);
301         spin_unlock_irqrestore(&gus->reg_lock, flags);                  
302         voice->vlo = vlo;
303         voice->vro = vro;
304 }
305
306 /*
307  *
308  */
309
310 static void sample_start(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_position_t position)
311 {
312         unsigned long flags;
313         unsigned int begin, addr, addr_end, addr_start;
314         int w_16;
315         simple_instrument_t *simple;
316         snd_seq_kinstr_t *instr;
317
318         instr = snd_seq_instr_find(gus->gf1.ilist, &voice->instr, 0, 1);
319         if (instr == NULL)
320                 return;
321         voice->instr = instr->instr;    /* copy ID to speedup aliases */
322         simple = KINSTR_DATA(instr);
323         begin = simple->address.memory << 4;
324         w_16 = simple->format & SIMPLE_WAVE_16BIT ? 0x04 : 0;
325         addr_start = simple->loop_start;
326         if (simple->format & SIMPLE_WAVE_LOOP) {
327                 addr_end = simple->loop_end;
328         } else {
329                 addr_end = (simple->size << 4) - (w_16 ? 40 : 24);
330         }
331         if (simple->format & SIMPLE_WAVE_BACKWARD) {
332                 addr = simple->loop_end;
333                 if (position < simple->loop_end)
334                         addr -= position;
335         } else {
336                 addr = position;
337         }
338         voice->control = 0x00;
339         voice->mode = 0x20;             /* enable offset registers */
340         if (simple->format & SIMPLE_WAVE_16BIT)
341                 voice->control |= 0x04;
342         if (simple->format & SIMPLE_WAVE_BACKWARD)
343                 voice->control |= 0x40;
344         if (simple->format & SIMPLE_WAVE_LOOP) {
345                 voice->control |= 0x08;
346         } else {
347                 voice->control |= 0x20;
348         }
349         if (simple->format & SIMPLE_WAVE_BIDIR)
350                 voice->control |= 0x10;
351         if (simple->format & SIMPLE_WAVE_ULAW)
352                 voice->mode |= 0x40;
353         if (w_16) {
354                 addr = ((addr << 1) & ~0x1f) | (addr & 0x0f);
355                 addr_start = ((addr_start << 1) & ~0x1f) | (addr_start & 0x0f);
356                 addr_end = ((addr_end << 1) & ~0x1f) | (addr_end & 0x0f);
357         }
358         addr += begin;
359         addr_start += begin;
360         addr_end += begin;
361         snd_gf1_stop_voice(gus, voice->number); 
362         spin_lock_irqsave(&gus->reg_lock, flags);
363         snd_gf1_select_voice(gus, voice->number);
364         snd_gf1_write16(gus, SNDRV_GF1_VW_FREQUENCY, voice->fc_register + voice->fc_lfo);
365         voice->venv_state = VENV_BEFORE;
366         voice->volume_control = 0x03;
367         snd_gf1_write_addr(gus, SNDRV_GF1_VA_START, addr_start, w_16);
368         snd_gf1_write_addr(gus, SNDRV_GF1_VA_END, addr_end, w_16);
369         snd_gf1_write_addr(gus, SNDRV_GF1_VA_CURRENT, addr, w_16);
370         if (!gus->gf1.enh_mode) {
371                 snd_gf1_write8(gus, SNDRV_GF1_VB_PAN, voice->gf1_pan);
372         } else {
373                 snd_gf1_write16(gus, SNDRV_GF1_VW_OFFSET_LEFT, voice->vlo);
374                 snd_gf1_write16(gus, SNDRV_GF1_VW_OFFSET_LEFT_FINAL, voice->vlo);
375                 snd_gf1_write16(gus, SNDRV_GF1_VW_OFFSET_RIGHT, voice->vro);
376                 snd_gf1_write16(gus, SNDRV_GF1_VW_OFFSET_RIGHT_FINAL, voice->vro);
377                 snd_gf1_write8(gus, SNDRV_GF1_VB_ACCUMULATOR, voice->effect_accumulator);
378                 snd_gf1_write16(gus, SNDRV_GF1_VW_EFFECT_VOLUME, voice->gf1_effect_volume);
379                 snd_gf1_write16(gus, SNDRV_GF1_VW_EFFECT_VOLUME_FINAL, voice->gf1_effect_volume);
380         }
381         spin_unlock_irqrestore(&gus->reg_lock, flags);
382         do_volume_envelope(gus, voice);
383         spin_lock_irqsave(&gus->reg_lock, flags);
384         snd_gf1_select_voice(gus, voice->number);
385         if (gus->gf1.enh_mode)
386                 snd_gf1_write8(gus, SNDRV_GF1_VB_MODE, voice->mode);
387         snd_gf1_write8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL, voice->control);
388         if (!gus->gf1.enh_mode) {
389                 snd_gf1_delay(gus);
390                 snd_gf1_write8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL, voice->control );
391         }
392         spin_unlock_irqrestore(&gus->reg_lock, flags);
393 #if 0
394         snd_gf1_print_voice_registers(gus);
395 #endif
396         voice->flags |= SNDRV_GF1_VFLG_RUNNING;
397         snd_seq_instr_free_use(gus->gf1.ilist, instr);
398 }
399
400 static void sample_stop(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_stop_mode_t mode)
401 {
402         unsigned char control;
403         unsigned long flags;
404
405         if (!(voice->flags & SNDRV_GF1_VFLG_RUNNING))
406                 return;
407         switch (mode) {
408         default:
409                 if (gus->gf1.volume_ramp > 0) {
410                         if (voice->venv_state < VENV_RELEASE) {
411                                 voice->venv_state = VENV_RELEASE;
412                                 do_volume_envelope(gus, voice);
413                         }
414                 }
415                 if (mode != SAMPLE_STOP_VENVELOPE) {
416                         snd_gf1_stop_voice(gus, voice->number);
417                         spin_lock_irqsave(&gus->reg_lock, flags);
418                         snd_gf1_select_voice(gus, voice->number);
419                         snd_gf1_write16(gus, SNDRV_GF1_VW_VOLUME, SNDRV_GF1_MIN_VOLUME);
420                         spin_unlock_irqrestore(&gus->reg_lock, flags);
421                         voice->flags &= ~SNDRV_GF1_VFLG_RUNNING;
422                 }
423                 break;
424         case SAMPLE_STOP_LOOP:          /* disable loop only */
425                 spin_lock_irqsave(&gus->reg_lock, flags);
426                 snd_gf1_select_voice(gus, voice->number);
427                 control = snd_gf1_read8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL);
428                 control &= ~(0x83 | 0x04);
429                 control |= 0x20;
430                 snd_gf1_write8(gus, SNDRV_GF1_VB_ADDRESS_CONTROL, control);
431                 spin_unlock_irqrestore(&gus->reg_lock, flags);
432                 break;
433         }
434 }
435
436 static void sample_freq(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_frequency_t freq)
437 {
438         unsigned long flags;
439
440         spin_lock_irqsave(&gus->reg_lock, flags);
441         voice->fc_register = snd_gf1_translate_freq(gus, freq);
442         snd_gf1_select_voice(gus, voice->number);
443         snd_gf1_write16(gus, SNDRV_GF1_VW_FREQUENCY, voice->fc_register + voice->fc_lfo);
444         spin_unlock_irqrestore(&gus->reg_lock, flags);
445 }
446
447 static void sample_volume(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_ev_volume_t *volume)
448 {
449         if (volume->volume >= 0) {
450                 volume->volume &= 0x3fff;
451                 voice->gf1_volume = snd_gf1_lvol_to_gvol_raw(volume->volume << 2) << 4;
452                 voice->venv_state_prev = VENV_SUSTAIN;
453                 voice->venv_state = VENV_VOLUME;
454                 do_volume_envelope(gus, voice);
455         }
456         if (volume->lr >= 0) {
457                 volume->lr &= 0x3fff;
458                 if (!gus->gf1.enh_mode) {
459                         voice->gf1_pan = (volume->lr >> 10) & 15;
460                         if (!gus->gf1.full_range_pan) {
461                                 if (voice->gf1_pan == 0)
462                                         voice->gf1_pan++;
463                                 if (voice->gf1_pan == 15)
464                                         voice->gf1_pan--;
465                         }
466                         voice->flags &= ~SNDRV_GF1_VFLG_PAN;    /* before */
467                         do_pan_envelope(gus, voice);
468                 } else {
469                         set_enhanced_pan(gus, voice, volume->lr >> 7);
470                 }
471         }
472 }
473
474 static void sample_loop(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_ev_loop_t *loop)
475 {
476         unsigned long flags;
477         int w_16 = voice->control & 0x04;
478         unsigned int begin, addr_start, addr_end;
479         simple_instrument_t *simple;
480         snd_seq_kinstr_t *instr;
481
482 #if 0
483         printk("voice_loop: start = 0x%x, end = 0x%x\n", loop->start, loop->end);
484 #endif
485         instr = snd_seq_instr_find(gus->gf1.ilist, &voice->instr, 0, 1);
486         if (instr == NULL)
487                 return;
488         voice->instr = instr->instr;    /* copy ID to speedup aliases */
489         simple = KINSTR_DATA(instr);
490         begin = simple->address.memory;
491         addr_start = loop->start;
492         addr_end = loop->end;
493         addr_start = (((addr_start << 1) & ~0x1f) | (addr_start & 0x0f)) + begin;
494         addr_end = (((addr_end << 1) & ~0x1f) | (addr_end & 0x0f)) + begin;
495         spin_lock_irqsave(&gus->reg_lock, flags);
496         snd_gf1_select_voice(gus, voice->number);
497         snd_gf1_write_addr(gus, SNDRV_GF1_VA_START, addr_start, w_16);
498         snd_gf1_write_addr(gus, SNDRV_GF1_VA_END, addr_end, w_16);
499         spin_unlock_irqrestore(&gus->reg_lock, flags);
500         snd_seq_instr_free_use(gus->gf1.ilist, instr);
501 }
502
503 static void sample_pos(snd_gus_card_t *gus, snd_gus_voice_t *voice, snd_seq_position_t position)
504 {
505         unsigned long flags;
506         int w_16 = voice->control & 0x04;
507         unsigned int begin, addr;
508         simple_instrument_t *simple;
509         snd_seq_kinstr_t *instr;
510
511 #if 0
512         printk("voice_loop: start = 0x%x, end = 0x%x\n", loop->start, loop->end);
513 #endif
514         instr = snd_seq_instr_find(gus->gf1.ilist, &voice->instr, 0, 1);
515         if (instr == NULL)
516                 return;
517         voice->instr = instr->instr;    /* copy ID to speedup aliases */
518         simple = KINSTR_DATA(instr);
519         begin = simple->address.memory;
520         addr = (((position << 1) & ~0x1f) | (position & 0x0f)) + begin;
521         spin_lock_irqsave(&gus->reg_lock, flags);
522         snd_gf1_select_voice(gus, voice->number);
523         snd_gf1_write_addr(gus, SNDRV_GF1_VA_CURRENT, addr, w_16);
524         spin_unlock_irqrestore(&gus->reg_lock, flags);
525         snd_seq_instr_free_use(gus->gf1.ilist, instr);
526 }
527
528 #if 0
529
530 static unsigned char get_effects_mask( ultra_card_t *card, int value )
531 {
532   if ( value > 7 ) return 0;
533   if ( card -> gf1.effects && card -> gf1.effects -> chip_type == ULTRA_EFFECT_CHIP_INTERWAVE )
534     return card -> gf1.effects -> chip.interwave.voice_output[ value ];
535   return 0;
536 }
537
538 #endif
539
540 static void sample_private1(snd_gus_card_t *card, snd_gus_voice_t *voice, unsigned char *data)
541 {
542 #if 0
543   unsigned long flags;
544   unsigned char uc;
545
546   switch ( *data ) {
547     case ULTRA_PRIV1_IW_EFFECT:
548       uc = get_effects_mask( card, ultra_get_byte( data, 4 ) );
549       uc |= get_effects_mask( card, ultra_get_byte( data, 4 ) >> 4 );
550       uc |= get_effects_mask( card, ultra_get_byte( data, 5 ) );
551       uc |= get_effects_mask( card, ultra_get_byte( data, 5 ) >> 4 );
552       voice -> data.simple.effect_accumulator = uc;
553       voice -> data.simple.effect_volume = ultra_translate_voice_volume( card, ultra_get_word( data, 2 ) ) << 4;
554       if ( !card -> gf1.enh_mode ) return;
555       if ( voice -> flags & VFLG_WAIT_FOR_START ) return;
556       if ( voice -> flags & VFLG_RUNNING )
557         {
558           CLI( &flags );
559           gf1_select_voice( card, voice -> number );
560           ultra_write8( card, GF1_VB_ACCUMULATOR, voice -> data.simple.effect_accumulator );
561           ultra_write16( card, GF1_VW_EFFECT_VOLUME_FINAL, voice -> data.simple.effect_volume );
562           STI( &flags );
563         }
564       break;
565    case ULTRA_PRIV1_IW_LFO:
566      ultra_lfo_command( card, voice -> number, data );
567   }
568 #endif
569 }
570
571 #if 0
572
573 /*
574  *
575  */
576
577 static void note_stop( ultra_card_t *card, ultra_voice_t *voice, int wait )
578 {
579 }
580
581 static void note_wait( ultra_card_t *card, ultra_voice_t *voice )
582 {
583 }
584
585 static void note_off( ultra_card_t *card, ultra_voice_t *voice )
586 {
587 }
588
589 static void note_volume( ultra_card_t *card, ultra_voice_t *voice )
590 {
591 }
592
593 static void note_pitchbend( ultra_card_t *card, ultra_voice_t *voice )
594 {
595 }
596
597 static void note_vibrato( ultra_card_t *card, ultra_voice_t *voice )
598 {
599 }
600
601 static void note_tremolo( ultra_card_t *card, ultra_voice_t *voice )
602 {
603 }
604
605 /*
606  *
607  */
608  
609 static void chn_trigger_down( ultra_card_t *card, ultra_channel_t *channel, ultra_instrument_t *instrument, unsigned char note, unsigned char velocity, unsigned char priority )
610 {
611 }
612
613 static void chn_trigger_up( ultra_card_t *card, ultra_note_t *note )
614 {
615 }
616
617 static void chn_control( ultra_card_t *card, ultra_channel_t *channel, unsigned short p1, unsigned short p2 )
618 {
619 }
620
621 /*
622  *
623  */
624  
625 #endif
626
627 void snd_gf1_simple_init(snd_gus_voice_t *voice)
628 {
629         voice->handler_wave = interrupt_wave;
630         voice->handler_volume = interrupt_volume;
631         voice->handler_effect = interrupt_effect;
632         voice->volume_change = NULL;
633         voice->sample_ops = &sample_ops;
634 }