Deleted Added
sdiff udiff text old ( 74797 ) new ( 75319 )
full compact
1/*
2 * Copyright (c) 1999 Cameron Grant <gandalf@vilnya.demon.co.uk>
3 * Portions Copyright by Luigi Rizzo - 1997-99
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 10 unchanged lines hidden (view full) ---

19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * $FreeBSD: head/sys/dev/sound/pcm/channel.c 74797 2001-03-25 21:43:24Z cg $
28 */
29
30#include <dev/sound/pcm/sound.h>
31
32#include "feeder_if.h"
33
34#define MIN_CHUNK_SIZE 256 /* for uiomove etc. */
35#define DMA_ALIGN_THRESHOLD 4

--- 143 unchanged lines hidden (view full) ---

179 DEB(
180 if (c->flags & CHN_F_CLOSING) {
181 sndbuf_dump(b, "b", 0x02);
182 sndbuf_dump(bs, "bs", 0x02);
183 })
184
185 amt = sndbuf_getfree(b);
186 ret = (amt > 0)? sndbuf_feed(bs, b, c, c->feeder, amt) : ENOSPC;
187 if (ret == 0)
188 chn_wakeup(c);
189/*
190 if (!(irqc & 63) || (ret != 0))
191 sndbuf_dump(b, "b:wrfeed", 0x03);
192*/
193 return ret;
194}
195

--- 523 unchanged lines hidden (view full) ---

719 DEB(printf("want speed %d, ", speed));
720 if (speed <= 0)
721 return EINVAL;
722 if (CANCHANGE(c)) {
723 r = 0;
724 c->speed = speed;
725 sndbuf_setspd(bs, speed);
726 RANGE(speed, chn_getcaps(c)->minspeed, chn_getcaps(c)->maxspeed);
727 sndbuf_setspd(b, speed);
728 DEB(printf("try speed %d, ", sndbuf_getspd(b)));
729 sndbuf_setspd(b, CHANNEL_SETSPEED(c->methods, c->devinfo, sndbuf_getspd(b)));
730 DEB(printf("got speed %d, ", sndbuf_getspd(b)));
731
732 delta = sndbuf_getspd(b) - sndbuf_getspd(bs);
733 if (delta < 0)
734 delta = -delta;
735
736 c->feederflags &= ~(1 << FEEDER_RATE);
737 if (delta > 500)

--- 46 unchanged lines hidden (view full) ---

784}
785
786static int
787chn_tryformat(struct pcm_channel *c, u_int32_t fmt)
788{
789 struct snd_dbuf *b = c->bufhard;
790 struct snd_dbuf *bs = c->bufsoft;
791 int r;
792 u_int32_t hwfmt;
793
794 CHN_LOCKASSERT(c);
795 if (CANCHANGE(c)) {
796 DEB(printf("want format %d\n", fmt));
797 c->format = fmt;
798 hwfmt = c->format;
799 c->feederflags &= ~(1 << FEEDER_FMT);
800 if (!fmtvalid(hwfmt, chn_getcaps(c)->fmtlist))
801 c->feederflags |= 1 << FEEDER_FMT;
802 r = chn_buildfeeder(c);
803 if (r == 0) {
804 hwfmt = c->feeder->desc->out;
805 sndbuf_setfmt(b, hwfmt);
806 sndbuf_setfmt(bs, fmt);
807 chn_resetbuf(c);
808 CHANNEL_SETFORMAT(c->methods, c->devinfo, hwfmt);
809 r = chn_tryspeed(c, c->speed);
810 }
811 return r;
812 } else
813 return EINVAL;
814}
815
816int

--- 136 unchanged lines hidden (view full) ---

953 return fmts;
954}
955
956static int
957chn_buildfeeder(struct pcm_channel *c)
958{
959 struct feeder_class *fc;
960 struct pcm_feederdesc desc;
961 u_int32_t tmp[2], src, dst, type, flags;
962
963 CHN_LOCKASSERT(c);
964 while (chn_removefeeder(c) == 0);
965 KASSERT((c->feeder == NULL), ("feeder chain not empty"));
966 c->align = sndbuf_getalign(c->bufsoft);
967 fc = feeder_getclass(NULL);
968 if (fc == NULL)
969 return EINVAL;
970 if (chn_addfeeder(c, fc, NULL))
971 return EINVAL;
972 c->feeder->desc->out = c->format;
973
974 flags = c->feederflags;
975 src = c->feeder->desc->out;
976 if ((c->flags & CHN_F_MAPPED) && (flags != 0))
977 return EINVAL;
978 DEB(printf("not mapped, flags %x, ", flags));
979 for (type = FEEDER_RATE; type <= FEEDER_LAST; type++) {
980 if (flags & (1 << type)) {
981 desc.type = type;
982 desc.in = 0;
983 desc.out = 0;
984 desc.flags = 0;
985 DEB(printf("find feeder type %d, ", type));
986 fc = feeder_getclass(&desc);
987 DEB(printf("got %p\n", fc));
988 if (fc == NULL)
989 return EINVAL;
990 dst = fc->desc->in;
991 if (src != dst) {
992 DEB(printf("build fmtchain from %x to %x: ", src, dst));
993 tmp[0] = dst;
994 tmp[1] = 0;
995 if (chn_fmtchain(c, tmp) == 0)
996 return EINVAL;
997 DEB(printf("ok\n"));
998 }
999 if (chn_addfeeder(c, fc, fc->desc))
1000 return EINVAL;
1001 src = fc->desc->out;
1002 DEB(printf("added feeder %p, output %x\n", fc, src));
1003 dst = 0;
1004 flags &= ~(1 << type);
1005 }
1006 }
1007 if (!fmtvalid(src, chn_getcaps(c)->fmtlist)) {
1008 if (chn_fmtchain(c, chn_getcaps(c)->fmtlist) == 0)
1009 return EINVAL;
1010 DEB(printf("built fmtchain from %x to %x\n", src, c->feeder->desc->out));
1011 flags &= ~(1 << FEEDER_FMT);
1012 }
1013 return 0;
1014}
1015
1016
1017