Linux-2.6.12-rc2
[linux-flexiantxendom0-natty.git] / sound / oss / emu10k1 / cardwo.c
1 /*
2  **********************************************************************
3  *     cardwo.c - PCM output HAL for emu10k1 driver
4  *     Copyright 1999, 2000 Creative Labs, Inc.
5  *
6  **********************************************************************
7  *
8  *     Date                 Author          Summary of changes
9  *     ----                 ------          ------------------
10  *     October 20, 1999     Bertrand Lee    base code release
11  *
12  **********************************************************************
13  *
14  *     This program is free software; you can redistribute it and/or
15  *     modify it under the terms of the GNU General Public License as
16  *     published by the Free Software Foundation; either version 2 of
17  *     the License, or (at your option) any later version.
18  *
19  *     This program is distributed in the hope that it will be useful,
20  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
21  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22  *     GNU General Public License for more details.
23  *
24  *     You should have received a copy of the GNU General Public
25  *     License along with this program; if not, write to the Free
26  *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
27  *     USA.
28  *
29  **********************************************************************
30  */
31
32 #include <linux/poll.h>
33 #include "hwaccess.h"
34 #include "8010.h"
35 #include "voicemgr.h"
36 #include "cardwo.h"
37 #include "audio.h"
38
39 static u32 samplerate_to_linearpitch(u32 samplingrate)
40 {
41         samplingrate = (samplingrate << 8) / 375;
42         return (samplingrate >> 1) + (samplingrate & 1);
43 }
44
45 static void query_format(struct emu10k1_wavedevice *wave_dev, struct wave_format *wave_fmt)
46 {
47         int i, j, do_passthrough = 0, is_ac3 = 0;
48         struct emu10k1_card *card = wave_dev->card;
49         struct woinst *woinst = wave_dev->woinst;
50
51         if ((wave_fmt->channels > 2) && (wave_fmt->id != AFMT_S16_LE) && (wave_fmt->id != AFMT_U8))
52                 wave_fmt->channels = 2;
53
54         if ((wave_fmt->channels < 1) || (wave_fmt->channels > WAVEOUT_MAXVOICES))
55                 wave_fmt->channels = 2;
56
57         if (wave_fmt->channels == 2)
58                 woinst->num_voices = 1;
59         else
60                 woinst->num_voices = wave_fmt->channels;
61
62         if (wave_fmt->samplingrate >= 0x2ee00)
63                 wave_fmt->samplingrate = 0x2ee00;
64
65         wave_fmt->passthrough = 0;
66         do_passthrough = is_ac3 = 0;
67
68         if (card->pt.selected)
69                 do_passthrough = 1;
70
71         switch (wave_fmt->id) {
72         case AFMT_S16_LE:
73                 wave_fmt->bitsperchannel = 16;
74                 break;
75         case AFMT_U8:
76                 wave_fmt->bitsperchannel = 8;
77                 break;
78         case AFMT_AC3:
79                 do_passthrough = 1;
80                 is_ac3 = 1;
81                 break;
82         default:
83                 wave_fmt->id = AFMT_S16_LE;
84                 wave_fmt->bitsperchannel = 16;
85                 break;
86         }       
87         if (do_passthrough) {
88                 /* currently only one waveout instance may use pass-through */
89                 if (woinst->state != WAVE_STATE_CLOSED || 
90                     card->pt.state != PT_STATE_INACTIVE ||
91                     (wave_fmt->samplingrate != 48000 && !is_ac3)) {
92                         DPF(2, "unable to set pass-through mode\n");
93                 } else if (USE_PT_METHOD1) {
94                         i = emu10k1_find_control_gpr(&card->mgr, card->pt.patch_name, card->pt.intr_gpr_name);
95                         j = emu10k1_find_control_gpr(&card->mgr, card->pt.patch_name, card->pt.enable_gpr_name);
96                         if (i < 0 || j < 0)
97                                 DPF(2, "unable to set pass-through mode\n");
98                         else {
99                                 wave_fmt->samplingrate = 48000;
100                                 wave_fmt->channels = 2;
101                                 card->pt.pos_gpr = emu10k1_find_control_gpr(&card->mgr, card->pt.patch_name,
102                                                                             card->pt.pos_gpr_name);
103                                 wave_fmt->passthrough = 1;
104                                 card->pt.intr_gpr = i;
105                                 card->pt.enable_gpr = j;
106                                 card->pt.state = PT_STATE_INACTIVE;
107                         
108                                 DPD(2, "is_ac3 is %d\n", is_ac3);
109                                 card->pt.ac3data = is_ac3;
110                                 wave_fmt->bitsperchannel = 16;
111                         }
112                 }else{
113                         DPF(2, "Using Passthrough Method 2\n");
114                         card->pt.enable_gpr = emu10k1_find_control_gpr(&card->mgr, card->pt.patch_name,
115                                                                        card->pt.enable_gpr_name);
116                         wave_fmt->passthrough = 2;
117                         wave_fmt->bitsperchannel = 16;
118                 }
119         }
120
121         wave_fmt->bytesperchannel = wave_fmt->bitsperchannel >> 3;
122         wave_fmt->bytespersample = wave_fmt->channels * wave_fmt->bytesperchannel;
123         wave_fmt->bytespersec = wave_fmt->bytespersample * wave_fmt->samplingrate;
124
125         if (wave_fmt->channels == 2)
126                 wave_fmt->bytespervoicesample = wave_fmt->channels * wave_fmt->bytesperchannel;
127         else
128                 wave_fmt->bytespervoicesample = wave_fmt->bytesperchannel;
129 }
130
131 static int get_voice(struct emu10k1_card *card, struct woinst *woinst, unsigned int voicenum)
132 {
133         struct emu_voice *voice = &woinst->voice[voicenum];
134
135         /* Allocate voices here, if no voices available, return error. */
136
137         voice->usage = VOICE_USAGE_PLAYBACK;
138
139         voice->flags = 0;
140
141         if (woinst->format.channels == 2)
142                 voice->flags |= VOICE_FLAGS_STEREO;
143
144         if (woinst->format.bitsperchannel == 16)
145                 voice->flags |= VOICE_FLAGS_16BIT;
146
147         if (emu10k1_voice_alloc(card, voice) < 0) {
148                 voice->usage = VOICE_USAGE_FREE;
149                 return -1;
150         }
151
152         /* Calculate pitch */
153         voice->initial_pitch = (u16) (srToPitch(woinst->format.samplingrate) >> 8);
154         voice->pitch_target = samplerate_to_linearpitch(woinst->format.samplingrate);
155
156         DPD(2, "Initial pitch --> %#x\n", voice->initial_pitch);
157
158         voice->startloop = (voice->mem.emupageindex << 12) /
159          woinst->format.bytespervoicesample;
160         voice->endloop = voice->startloop + woinst->buffer.size / woinst->format.bytespervoicesample;
161         voice->start = voice->startloop;
162
163         
164         voice->params[0].volume_target = 0xffff;
165         voice->params[0].initial_fc = 0xff;
166         voice->params[0].initial_attn = 0x00;
167         voice->params[0].byampl_env_sustain = 0x7f;
168         voice->params[0].byampl_env_decay = 0x7f;
169
170         
171         if (voice->flags & VOICE_FLAGS_STEREO) {
172                 if (woinst->format.passthrough == 2) {
173                         voice->params[0].send_routing  = voice->params[1].send_routing  = card->waveout.send_routing[ROUTE_PT];
174                         voice->params[0].send_routing2 = voice->params[1].send_routing2 = card->waveout.send_routing2[ROUTE_PT];
175                         voice->params[0].send_dcba = 0xff;
176                         voice->params[1].send_dcba = 0xff00;
177                         voice->params[0].send_hgfe = voice->params[1].send_hgfe=0;
178                 } else {
179                         voice->params[0].send_dcba = card->waveout.send_dcba[SEND_LEFT];
180                         voice->params[0].send_hgfe = card->waveout.send_hgfe[SEND_LEFT];
181                         voice->params[1].send_dcba = card->waveout.send_dcba[SEND_RIGHT];
182                         voice->params[1].send_hgfe = card->waveout.send_hgfe[SEND_RIGHT];
183
184                         if (woinst->device) {
185                                 // /dev/dps1
186                                 voice->params[0].send_routing  = voice->params[1].send_routing  = card->waveout.send_routing[ROUTE_PCM1];
187                                 voice->params[0].send_routing2 = voice->params[1].send_routing2 = card->waveout.send_routing2[ROUTE_PCM1];
188                         } else {
189                                 voice->params[0].send_routing  = voice->params[1].send_routing  = card->waveout.send_routing[ROUTE_PCM];
190                                 voice->params[0].send_routing2 = voice->params[1].send_routing2 = card->waveout.send_routing2[ROUTE_PCM];
191                         }
192                 }
193                 
194                 voice->params[1].volume_target = 0xffff;
195                 voice->params[1].initial_fc = 0xff;
196                 voice->params[1].initial_attn = 0x00;
197                 voice->params[1].byampl_env_sustain = 0x7f;
198                 voice->params[1].byampl_env_decay = 0x7f;
199         } else {
200                 if (woinst->num_voices > 1) {
201                         // Multichannel pcm
202                         voice->params[0].send_dcba=0xff;
203                         voice->params[0].send_hgfe=0;
204                         if (card->is_audigy) {
205                                 voice->params[0].send_routing = 0x3f3f3f00 + card->mchannel_fx + voicenum;
206                                 voice->params[0].send_routing2 = 0x3f3f3f3f;
207                         } else {
208                                 voice->params[0].send_routing = 0xfff0 + card->mchannel_fx + voicenum;
209                         }
210                         
211                 } else {
212                         voice->params[0].send_dcba = card->waveout.send_dcba[SEND_MONO];
213                         voice->params[0].send_hgfe = card->waveout.send_hgfe[SEND_MONO];
214
215                         if (woinst->device) {
216                                 voice->params[0].send_routing = card->waveout.send_routing[ROUTE_PCM1];
217                                 voice->params[0].send_routing2 = card->waveout.send_routing2[ROUTE_PCM1];
218                         } else {
219                                 voice->params[0].send_routing = card->waveout.send_routing[ROUTE_PCM];
220                                 voice->params[0].send_routing2 = card->waveout.send_routing2[ROUTE_PCM];
221                         }
222                 }
223         }
224
225         DPD(2, "voice: startloop=%#x, endloop=%#x\n", voice->startloop, voice->endloop);
226
227         emu10k1_voice_playback_setup(voice);
228
229         return 0;
230 }
231
232 int emu10k1_waveout_open(struct emu10k1_wavedevice *wave_dev)
233 {
234         struct emu10k1_card *card = wave_dev->card;
235         struct woinst *woinst = wave_dev->woinst;
236         struct waveout_buffer *buffer = &woinst->buffer;
237         unsigned int voicenum;
238         u16 delay;
239
240         DPF(2, "emu10k1_waveout_open()\n");
241
242         for (voicenum = 0; voicenum < woinst->num_voices; voicenum++) {
243                 if (emu10k1_voice_alloc_buffer(card, &woinst->voice[voicenum].mem, woinst->buffer.pages) < 0) {
244                         ERROR();
245                         emu10k1_waveout_close(wave_dev);
246                         return -1;
247                 }
248
249                 if (get_voice(card, woinst, voicenum) < 0) {
250                         ERROR();
251                         emu10k1_waveout_close(wave_dev);
252                         return -1;
253                 }
254         }
255
256         buffer->fill_silence = 0;
257         buffer->silence_bytes = 0;
258         buffer->silence_pos = 0;
259         buffer->hw_pos = 0;
260         buffer->free_bytes = woinst->buffer.size;
261
262         delay = (48000 * woinst->buffer.fragment_size) /
263                  (woinst->format.samplingrate * woinst->format.bytespervoicesample);
264
265         emu10k1_timer_install(card, &woinst->timer, delay);
266
267         woinst->state = WAVE_STATE_OPEN;
268
269         return 0;
270 }
271
272 void emu10k1_waveout_close(struct emu10k1_wavedevice *wave_dev)
273 {
274         struct emu10k1_card *card = wave_dev->card;
275         struct woinst *woinst = wave_dev->woinst;
276         unsigned int voicenum;
277
278         DPF(2, "emu10k1_waveout_close()\n");
279
280         emu10k1_waveout_stop(wave_dev);
281
282         emu10k1_timer_uninstall(card, &woinst->timer);
283
284         for (voicenum = 0; voicenum < woinst->num_voices; voicenum++) {
285                 emu10k1_voice_free(&woinst->voice[voicenum]);
286                 emu10k1_voice_free_buffer(card, &woinst->voice[voicenum].mem);
287         }
288
289         woinst->state = WAVE_STATE_CLOSED;
290 }
291
292 void emu10k1_waveout_start(struct emu10k1_wavedevice *wave_dev)
293 {
294         struct emu10k1_card *card = wave_dev->card;
295         struct woinst *woinst = wave_dev->woinst;
296         struct pt_data *pt = &card->pt;
297
298         DPF(2, "emu10k1_waveout_start()\n");
299
300         if (woinst->format.passthrough == 2) {
301                 emu10k1_pt_setup(wave_dev);
302                 sblive_writeptr(card, (card->is_audigy ? A_GPR_BASE : GPR_BASE) + pt->enable_gpr, 0, 1);
303                 pt->state = PT_STATE_PLAYING;
304         }
305
306         /* Actual start */
307         emu10k1_voices_start(woinst->voice, woinst->num_voices, woinst->total_played);
308
309         emu10k1_timer_enable(card, &woinst->timer);
310
311         woinst->state |= WAVE_STATE_STARTED;
312 }
313
314 int emu10k1_waveout_setformat(struct emu10k1_wavedevice *wave_dev, struct wave_format *format)
315 {
316         struct emu10k1_card *card = wave_dev->card;
317         struct woinst *woinst = wave_dev->woinst;
318         unsigned int voicenum;
319         u16 delay;
320
321         DPF(2, "emu10k1_waveout_setformat()\n");
322
323         if (woinst->state & WAVE_STATE_STARTED)
324                 return -1;
325
326         query_format(wave_dev, format);
327
328         if (woinst->format.samplingrate != format->samplingrate ||
329             woinst->format.channels != format->channels ||
330             woinst->format.bitsperchannel != format->bitsperchannel) {
331
332                 woinst->format = *format;
333
334                 if (woinst->state == WAVE_STATE_CLOSED)
335                         return 0;
336
337                 emu10k1_timer_uninstall(card, &woinst->timer);
338
339                 for (voicenum = 0; voicenum < woinst->num_voices; voicenum++) {
340                         emu10k1_voice_free(&woinst->voice[voicenum]);
341
342                         if (get_voice(card, woinst, voicenum) < 0) {
343                                 ERROR();
344                                 emu10k1_waveout_close(wave_dev);
345                                 return -1;
346                         }
347                 }
348
349                 delay = (48000 * woinst->buffer.fragment_size) /
350                          (woinst->format.samplingrate * woinst->format.bytespervoicesample);
351
352                 emu10k1_timer_install(card, &woinst->timer, delay);
353         }
354
355         return 0;
356 }
357
358 void emu10k1_waveout_stop(struct emu10k1_wavedevice *wave_dev)
359 {
360         struct emu10k1_card *card = wave_dev->card;
361         struct woinst *woinst = wave_dev->woinst;
362
363         DPF(2, "emu10k1_waveout_stop()\n");
364
365         if (!(woinst->state & WAVE_STATE_STARTED))
366                 return;
367
368         emu10k1_timer_disable(card, &woinst->timer);
369
370         /* Stop actual voices */
371         emu10k1_voices_stop(woinst->voice, woinst->num_voices);
372
373         emu10k1_waveout_update(woinst);
374
375         woinst->state &= ~WAVE_STATE_STARTED;
376 }
377
378 /**
379  * emu10k1_waveout_getxfersize -
380  *
381  * gives the total free bytes on the voice buffer, including silence bytes
382  * (basically: total_free_bytes = free_bytes + silence_bytes).
383  *
384  */
385 void emu10k1_waveout_getxfersize(struct woinst *woinst, u32 *total_free_bytes)
386 {
387         struct waveout_buffer *buffer = &woinst->buffer;
388         int pending_bytes;
389
390         if (woinst->mmapped) {
391                 *total_free_bytes = buffer->free_bytes;
392                 return;
393         }
394
395         pending_bytes = buffer->size - buffer->free_bytes;
396
397         buffer->fill_silence = (pending_bytes < (signed) buffer->fragment_size * 2) ? 1 : 0;
398
399         if (pending_bytes > (signed) buffer->silence_bytes) {
400                 *total_free_bytes = (buffer->free_bytes + buffer->silence_bytes);
401         } else {
402                 *total_free_bytes = buffer->size;
403                 buffer->silence_bytes = pending_bytes;
404                 if (pending_bytes < 0) {
405                         buffer->silence_pos = buffer->hw_pos;
406                         buffer->silence_bytes = 0;
407                         buffer->free_bytes = buffer->size;
408                         DPF(1, "buffer underrun\n");
409                 }
410         }
411 }
412
413 /**
414  * copy_block -
415  *
416  * copies a block of pcm data to a voice buffer.
417  * Notice that the voice buffer is actually a set of disjointed memory pages.
418  *
419  */
420 static void copy_block(void **dst, u32 str, u8 __user *src, u32 len)
421 {
422         unsigned int pg;
423         unsigned int pgoff;
424         unsigned int k;
425
426         pg = str / PAGE_SIZE;
427         pgoff = str % PAGE_SIZE;
428
429         if (len > PAGE_SIZE - pgoff) {
430                 k = PAGE_SIZE - pgoff;
431                 if (__copy_from_user((u8 *)dst[pg] + pgoff, src, k))
432                         return;
433                 len -= k;
434                 while (len > PAGE_SIZE) {
435                         if (__copy_from_user(dst[++pg], src + k, PAGE_SIZE))
436                                 return;
437                         k += PAGE_SIZE;
438                         len -= PAGE_SIZE;
439                 }
440                 if (__copy_from_user(dst[++pg], src + k, len))
441                         return;
442
443         } else
444                 __copy_from_user((u8 *)dst[pg] + pgoff, src, len);
445 }
446
447 /**
448  * copy_ilv_block -
449  *
450  * copies a block of pcm data containing n interleaved channels to n mono voice buffers.
451  * Notice that the voice buffer is actually a set of disjointed memory pages.
452  *
453  */
454 static void copy_ilv_block(struct woinst *woinst, u32 str, u8 __user *src, u32 len) 
455 {
456         unsigned int pg;
457         unsigned int pgoff;
458         unsigned int voice_num;
459         struct emu_voice *voice = woinst->voice;
460
461         pg = str / PAGE_SIZE;
462         pgoff = str % PAGE_SIZE;
463
464         while (len) { 
465                 for (voice_num = 0; voice_num < woinst->num_voices; voice_num++) {
466                         if (__copy_from_user((u8 *)(voice[voice_num].mem.addr[pg]) + pgoff, src, woinst->format.bytespervoicesample))
467                                 return;
468                         src += woinst->format.bytespervoicesample;
469                 }
470
471                 len -= woinst->format.bytespervoicesample;
472
473                 pgoff += woinst->format.bytespervoicesample;
474                 if (pgoff >= PAGE_SIZE) {
475                         pgoff = 0;
476                         pg++;
477                 }
478         }
479 }
480
481 /**
482  * fill_block -
483  *
484  * fills a set voice buffers with a block of a given sample.
485  *
486  */
487 static void fill_block(struct woinst *woinst, u32 str, u8 data, u32 len)
488 {
489         unsigned int pg;
490         unsigned int pgoff;
491         unsigned int voice_num;
492         struct emu_voice *voice = woinst->voice;
493         unsigned int  k;
494
495         pg = str / PAGE_SIZE;
496         pgoff = str % PAGE_SIZE;
497
498         if (len > PAGE_SIZE - pgoff) {
499                 k = PAGE_SIZE - pgoff;
500                 for (voice_num = 0; voice_num < woinst->num_voices; voice_num++)
501                         memset((u8 *)voice[voice_num].mem.addr[pg] + pgoff, data, k);
502                 len -= k;
503                 while (len > PAGE_SIZE) {
504                         pg++;
505                         for (voice_num = 0; voice_num < woinst->num_voices; voice_num++)
506                                 memset(voice[voice_num].mem.addr[pg], data, PAGE_SIZE);
507
508                         len -= PAGE_SIZE;
509                 }
510                 pg++;
511                 for (voice_num = 0; voice_num < woinst->num_voices; voice_num++)
512                         memset(voice[voice_num].mem.addr[pg], data, len);
513
514         } else {
515                 for (voice_num = 0; voice_num < woinst->num_voices; voice_num++)
516                         memset((u8 *)voice[voice_num].mem.addr[pg] + pgoff, data, len);
517         }
518 }
519
520 /**
521  * emu10k1_waveout_xferdata -
522  *
523  * copies pcm data to the voice buffer. Silence samples
524  * previously added to the buffer are overwritten.
525  *
526  */
527 void emu10k1_waveout_xferdata(struct woinst *woinst, u8 __user *data, u32 *size)
528 {
529         struct waveout_buffer *buffer = &woinst->buffer;
530         struct voice_mem *mem = &woinst->voice[0].mem;
531         u32 sizetocopy, sizetocopy_now, start;
532         unsigned long flags;
533
534         sizetocopy = min_t(u32, buffer->size, *size);
535         *size = sizetocopy;
536
537         if (!sizetocopy)
538                 return;
539         
540         spin_lock_irqsave(&woinst->lock, flags);
541         start = (buffer->size + buffer->silence_pos - buffer->silence_bytes) % buffer->size;
542
543         if (sizetocopy > buffer->silence_bytes) {
544                 buffer->silence_pos += sizetocopy - buffer->silence_bytes;
545                 buffer->free_bytes -= sizetocopy - buffer->silence_bytes;
546                 buffer->silence_bytes = 0;
547         } else
548                 buffer->silence_bytes -= sizetocopy;
549
550         spin_unlock_irqrestore(&woinst->lock, flags);
551
552         sizetocopy_now = buffer->size - start;
553         if (sizetocopy > sizetocopy_now) {
554                 sizetocopy -= sizetocopy_now;
555                 if (woinst->num_voices > 1) {
556                         copy_ilv_block(woinst, start, data, sizetocopy_now);
557                         copy_ilv_block(woinst, 0, data + sizetocopy_now * woinst->num_voices, sizetocopy);
558                 } else {
559                         copy_block(mem->addr, start, data, sizetocopy_now);
560                         copy_block(mem->addr, 0, data + sizetocopy_now, sizetocopy);
561                 }
562         } else {
563                 if (woinst->num_voices > 1)
564                         copy_ilv_block(woinst, start, data, sizetocopy);
565                 else
566                         copy_block(mem->addr, start, data, sizetocopy);
567         }
568 }
569
570 /**
571  * emu10k1_waveout_fillsilence -
572  *
573  * adds samples of silence to the voice buffer so that we
574  * don't loop over stale pcm data.
575  *
576  */
577 void emu10k1_waveout_fillsilence(struct woinst *woinst)
578 {
579         struct waveout_buffer *buffer = &woinst->buffer;
580         u32 sizetocopy, sizetocopy_now, start;
581         u8 filldata;
582         unsigned long flags;
583
584         sizetocopy = buffer->fragment_size;
585
586         if (woinst->format.bitsperchannel == 16)
587                 filldata = 0x00;
588         else
589                 filldata = 0x80;
590
591         spin_lock_irqsave(&woinst->lock, flags);
592         buffer->silence_bytes += sizetocopy;
593         buffer->free_bytes -= sizetocopy;
594         buffer->silence_pos %= buffer->size;
595         start = buffer->silence_pos;
596         buffer->silence_pos += sizetocopy;
597         spin_unlock_irqrestore(&woinst->lock, flags);
598
599         sizetocopy_now = buffer->size - start;
600
601         if (sizetocopy > sizetocopy_now) {
602                 sizetocopy -= sizetocopy_now;
603                 fill_block(woinst, start, filldata, sizetocopy_now);
604                 fill_block(woinst, 0, filldata, sizetocopy);
605         } else {
606                 fill_block(woinst, start, filldata, sizetocopy);
607         }
608 }
609
610 /**
611  * emu10k1_waveout_update -
612  *
613  * updates the position of the voice buffer hardware pointer (hw_pos)
614  * and the number of free bytes on the buffer (free_bytes).
615  * The free bytes _don't_ include silence bytes that may have been
616  * added to the buffer.
617  *
618  */
619 void emu10k1_waveout_update(struct woinst *woinst)
620 {
621         u32 hw_pos;
622         u32 diff;
623
624         /* There is no actual start yet */
625         if (!(woinst->state & WAVE_STATE_STARTED)) {
626                 hw_pos = woinst->buffer.hw_pos;
627         } else {
628                 /* hw_pos in sample units */
629                 hw_pos = sblive_readptr(woinst->voice[0].card, CCCA_CURRADDR, woinst->voice[0].num);
630
631                 if(hw_pos < woinst->voice[0].start)
632                         hw_pos += woinst->buffer.size / woinst->format.bytespervoicesample - woinst->voice[0].start;
633                 else
634                         hw_pos -= woinst->voice[0].start;
635
636                 hw_pos *= woinst->format.bytespervoicesample;
637         }
638
639         diff = (woinst->buffer.size + hw_pos - woinst->buffer.hw_pos) % woinst->buffer.size;
640         woinst->total_played += diff;
641         woinst->buffer.free_bytes += diff;
642         woinst->buffer.hw_pos = hw_pos;
643 }