From owner-freebsd-multimedia Tue Jul 29 00:21:26 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.5/8.8.5) id AAA20246 for multimedia-outgoing; Tue, 29 Jul 1997 00:21:26 -0700 (PDT) Received: from rah.star-gate.com (rah.star-gate.com [204.188.121.18]) by hub.freebsd.org (8.8.5/8.8.5) with ESMTP id AAA20207 for ; Tue, 29 Jul 1997 00:21:20 -0700 (PDT) Received: from rah.star-gate.com (localhost.star-gate.com [127.0.0.1]) by rah.star-gate.com (8.8.5/8.8.5) with ESMTP id AAA02594; Tue, 29 Jul 1997 00:21:10 -0700 (PDT) Message-Id: <199707290721.AAA02594@rah.star-gate.com> X-Mailer: exmh version 2.0gamma 1/27/96 To: Johan Larsson cc: freebsd-multimedia@freebsd.org Subject: Re: guspnp12b In-reply-to: Your message of "Tue, 29 Jul 1997 08:34:33 +0200." Mime-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Date: Tue, 29 Jul 1997 00:21:10 -0700 From: Amancio Hasty Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by hub.freebsd.org id AAA20219 Sender: owner-freebsd-multimedia@freebsd.org X-Loop: FreeBSD.org Precedence: bulk Tnks, I will try to fix the last dma bug . It has to deal with changing the size of the last dma request. Typically, with auto dma the sound card cycles thru the dma buffer at fixed step sizes and when the last output block of a sound stream is sent out it is usually not the same step size;hence, the driver gets into trouble well at least with the sb16 cards. Will try to fix it however if it looks too hard that is just the way that is going to be given that Luigi is revamping the dma algorithm , I rather fix for good on his version. Here is specifically whats going on: sb16_dsp.c:sb16_dsp_output_block(int dev, u_long buf, int count, int intrflag, int dma_restart) { u_long flags, cnt; cnt = count; if (dsp_16bit) cnt >>= 1; cnt--; if (audio_devs[dev]->flags & DMA_AUTOMODE && intrflag && cnt==dsp_count) { irq_mode = IMODE_OUTPUT; intr_active = 1; return; /* Auto mode on. No need to react */ } flags = splhigh(); if (dma_restart) { sb16_dsp_halt(dev); DMAbuf_start_dma(dev, buf, count, 1); } sb_dsp_command(0x41); sb_dsp_command((u_char) ((dsp_current_speed >> 8) & 0xff)); sb_dsp_command((u_char) (dsp_current_speed & 0xff)); sb_dsp_command((u_char) (dsp_16bit ? 0xb6 : 0xc6)); dsp_count = cnt; sb_dsp_command((u_char) ((dsp_stereo ? 0x20 : 0) + (dsp_16bit ? 0x10 : 0))); /* here on the last output block we write a block which is usually * less than dsp_count */ sb_dsp_command((u_char) (cnt & 0xff)); sb_dsp_command((u_char) (cnt >> 8)); irq_mode = IMODE_OUTPUT; intr_active = 1; splx(flags); } Here is an interesting reading, in case someone wants to try to fix the problem. ³ DSP commands ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ D0 - Pause 8-bit DMA mode digitized sound I/O initiated by command Cxh. Applicable to both single-cycle and auto-initialized DMA I/O. D4 - Continue 8-bit DMA mode digitized sound I/O paused using command D0. Applicable to both single-cycle and auto-initialzied DMA I/O. D5 - Pause 16-bit DMA mode digitized sound I/O initiated by command Bxh. Applicable to both single-cycle and auto-initialized DMA I/O. D6 - Continue 16-bit DMA mode digitized sound I/O paused using command D5 Applicable to both single-cycle and auto-initialized DMA I/O. D9 - Exit 16-bit auto-initialized DMA mode digitized sound I/O after the end of the current block. DA - Exit 8-bit auto-initialized DMA mode digitized sound I/O after the end of the current block. When single-cycle DMA is used, sound output stops at the end of each block. The interrupt handler can start another transfer, but there will be a break in output. This causes a click between each block, reducing sound quality. When auto-initialized DMA is used, sound output loops around at the end of the buffer. The DMA controller keeps transfering the same block of memory that the DMA transfer was initiated with. When the end of the buffer is reached, it will start sending the buffer again by auto-initializing the current offset and count registers with the values stored in the base offset and count registers. The usual method for achieving click-less output is to allocate a buffer and divide it into two blocks. Program the DMA controller with the length of the whole buffer, but program the SB16 with the length of a block. (Half of the buffer) An interrupt occurs for each sound card block, so two interrupts will occur each time the buffer is played, once at the midpoint (Start of the second block) and once at the end (In effect, the start of the first block) The interrupt handler should copy data into the block that was just finished so that the data is ready when it is needed for output. The programming procedure for an auto-initialized DMA transfer is identical to the procedure for a single-cycle DMA transfer, except that bit 4 of the DMA mode register and bit 3 of the DSP command are set. Upon interrupt when using auto-initialized DMA: 1) Copy next chunk into output buffer block that just finished 2) Acknowledge the interrupt with the SB by reading from port 2xE for 8-bit sound or port 2xF for 16-bit sound. 3) Acknowledge the end of interrupt with the PIC by writing 20h to port 20h. If the sound card is on IRQ8-15, you must also write 20h to A0h. To stop sound immediately: 8-bit - Write DSP command D0h (Pause 8-bit DMA mode digitized sound I/O) 16-bit - Write DSP command D5h (Pause 16-bit DMA mode digitized sound I/O) (Stops sound immediately, without an interrupt) To stop the sound at the end of the currently block: 8-bit - Write DSP command DAh (Stop 8-bit auto-init DMA sound I/O) 16-bit - Write DSP command D9h (Stop 16-bit auto-init DMA sound I/O) (These two commands will stop the sound at the end of the current block. If your program is not prepared for an interrupt after output is finished, it may cause problems) You can also end auto-initialized mode by reprogramming the DSP for single-cycle mode. The card then switches from A/I mode to S/C mode after the next interrupt. It will then contiue to play or record for the length specified, generate an interrupt and stop. This will allow you to stop output exactly at the end of the data, without requiring the remainder of the DMA buffer to be filled with silence. This technique may or may not be useful to you. I would recommend using the pause commands documented in in the immediate stop section unless another method is more suited to your purpose. Best Regards, Amancio >From The Desk Of Johan Larsson : > I have tried this one now, but very quickly, because i had to rebuild my > system last night and it toook 11.5 hours(ugh, should it take this > long?, i have a 486 dx4/100 with 32meg ram). > > Back to guspnp12b. I noticed just one major thing, and that was that it > repeated itself the last half of a second during playback. Otherwise the > driver seems very stable. > > Another thing(but i guess that has to do with the fact that i rebuilt my > system last night) is that suddenly the playback speed got slower and > slower after each playback (it starts about with a quarter of normal > speed). I ran a 0718 kernel on my last night -current system. > > Amancio, you said that i should rebuild my mixer, but now it doesn't work > at all.. I'll rebuild my kernel today and get back to you of how it > worked then. > > But i really think now this driver is ready to replace the current one, > it is just these flaws that needs to be fixed. :-) > > Great work Amancio! > > ./johan > > -- > * mailto:gozer@ludd.luth.se * http://www.ludd.luth.se/users/gozer/ * > * finger gozer@mother.ludd.luth.se for more information... +-+-+-+ * > * Powered by FreeBSD. http://www.se.freebsd.org/ +-+-+-+-+-+-+-+-+ * > >