Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  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 }
644 
  This page was automatically generated by the LXR engine.