channel.c (168243) | channel.c (170161) |
---|---|
1/*- 2 * Copyright (c) 1999 Cameron Grant <cg@freebsd.org> 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: --- 17 unchanged lines hidden (view full) --- 26 */ 27 28#include "opt_isa.h" 29 30#include <dev/sound/pcm/sound.h> 31 32#include "feeder_if.h" 33 | 1/*- 2 * Copyright (c) 1999 Cameron Grant <cg@freebsd.org> 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: --- 17 unchanged lines hidden (view full) --- 26 */ 27 28#include "opt_isa.h" 29 30#include <dev/sound/pcm/sound.h> 31 32#include "feeder_if.h" 33 |
34SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pcm/channel.c 168243 2007-04-02 03:03:06Z ariff $"); | 34SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pcm/channel.c 170161 2007-05-31 18:43:33Z ariff $"); |
35 36#define MIN_CHUNK_SIZE 256 /* for uiomove etc. */ 37#if 0 38#define DMA_ALIGN_THRESHOLD 4 39#define DMA_ALIGN_MASK (~(DMA_ALIGN_THRESHOLD - 1)) 40#endif 41 42#define CHN_STARTED(c) ((c)->flags & CHN_F_TRIGGERED) --- 122 unchanged lines hidden (view full) --- 165 166static void 167chn_lockinit(struct pcm_channel *c, int dir) 168{ 169 switch(dir) { 170 case PCMDIR_PLAY: 171 c->lock = snd_mtxcreate(c->name, "pcm play channel"); 172 break; | 35 36#define MIN_CHUNK_SIZE 256 /* for uiomove etc. */ 37#if 0 38#define DMA_ALIGN_THRESHOLD 4 39#define DMA_ALIGN_MASK (~(DMA_ALIGN_THRESHOLD - 1)) 40#endif 41 42#define CHN_STARTED(c) ((c)->flags & CHN_F_TRIGGERED) --- 122 unchanged lines hidden (view full) --- 165 166static void 167chn_lockinit(struct pcm_channel *c, int dir) 168{ 169 switch(dir) { 170 case PCMDIR_PLAY: 171 c->lock = snd_mtxcreate(c->name, "pcm play channel"); 172 break; |
173 case PCMDIR_PLAY_VIRTUAL: 174 c->lock = snd_mtxcreate(c->name, "pcm virtual play channel"); 175 break; |
|
173 case PCMDIR_REC: 174 c->lock = snd_mtxcreate(c->name, "pcm record channel"); 175 break; | 176 case PCMDIR_REC: 177 c->lock = snd_mtxcreate(c->name, "pcm record channel"); 178 break; |
176 case PCMDIR_VIRTUAL: 177 c->lock = snd_mtxcreate(c->name, "pcm virtual play channel"); | 179 case PCMDIR_REC_VIRTUAL: 180 c->lock = snd_mtxcreate(c->name, "pcm virtual record channel"); |
178 break; 179 case 0: 180 c->lock = snd_mtxcreate(c->name, "pcm fake channel"); 181 break; 182 } 183 184 cv_init(&c->cv, c->name); 185} --- 43 unchanged lines hidden (view full) --- 229 sndbuf_updateprevtotal(bs); 230 return 1; 231} 232 233static void 234chn_wakeup(struct pcm_channel *c) 235{ 236 struct snd_dbuf *bs = c->bufsoft; | 181 break; 182 case 0: 183 c->lock = snd_mtxcreate(c->name, "pcm fake channel"); 184 break; 185 } 186 187 cv_init(&c->cv, c->name); 188} --- 43 unchanged lines hidden (view full) --- 232 sndbuf_updateprevtotal(bs); 233 return 1; 234} 235 236static void 237chn_wakeup(struct pcm_channel *c) 238{ 239 struct snd_dbuf *bs = c->bufsoft; |
237 struct pcmchan_children *pce; | 240 struct pcm_channel *ch; |
238 239 CHN_LOCKASSERT(c); | 241 242 CHN_LOCKASSERT(c); |
240 if (SLIST_EMPTY(&c->children)) { | 243 if (CHN_EMPTY(c, children)) { |
241 if (SEL_WAITING(sndbuf_getsel(bs)) && chn_polltrigger(c)) 242 selwakeuppri(sndbuf_getsel(bs), PRIBIO); | 244 if (SEL_WAITING(sndbuf_getsel(bs)) && chn_polltrigger(c)) 245 selwakeuppri(sndbuf_getsel(bs), PRIBIO); |
243 wakeup_one(bs); | 246 } else if (CHN_EMPTY(c, children.busy)) { 247 CHN_FOREACH(ch, c, children) { 248 CHN_LOCK(ch); 249 chn_wakeup(ch); 250 CHN_UNLOCK(ch); 251 } |
244 } else { | 252 } else { |
245 SLIST_FOREACH(pce, &c->children, link) { 246 CHN_LOCK(pce->channel); 247 chn_wakeup(pce->channel); 248 CHN_UNLOCK(pce->channel); | 253 CHN_FOREACH(ch, c, children.busy) { 254 CHN_LOCK(ch); 255 chn_wakeup(ch); 256 CHN_UNLOCK(ch); |
249 } 250 } | 257 } 258 } |
259 if (c->flags & CHN_F_SLEEPING) 260 wakeup_one(bs); |
|
251} 252 253static int 254chn_sleep(struct pcm_channel *c, char *str, int timeout) 255{ 256 struct snd_dbuf *bs = c->bufsoft; 257 int ret; 258 259 CHN_LOCKASSERT(c); | 261} 262 263static int 264chn_sleep(struct pcm_channel *c, char *str, int timeout) 265{ 266 struct snd_dbuf *bs = c->bufsoft; 267 int ret; 268 269 CHN_LOCKASSERT(c); |
270 271 c->flags |= CHN_F_SLEEPING; |
|
260#ifdef USING_MUTEX 261 ret = msleep(bs, c->lock, PRIBIO | PCATCH, str, timeout); 262#else 263 ret = tsleep(bs, PRIBIO | PCATCH, str, timeout); 264#endif | 272#ifdef USING_MUTEX 273 ret = msleep(bs, c->lock, PRIBIO | PCATCH, str, timeout); 274#else 275 ret = tsleep(bs, PRIBIO | PCATCH, str, timeout); 276#endif |
277 c->flags &= ~CHN_F_SLEEPING; |
|
265 266 return ret; 267} 268 269/* 270 * chn_dmaupdate() tracks the status of a dma transfer, 271 * updating pointers. 272 */ --- 219 unchanged lines hidden (view full) --- 492#if 0 493 amt = sndbuf_getready(b); 494 if (sndbuf_getfree(bs) < amt) { 495 c->xruns++; 496 amt = sndbuf_getfree(bs); 497 } 498#endif 499 amt = sndbuf_getfree(bs); | 278 279 return ret; 280} 281 282/* 283 * chn_dmaupdate() tracks the status of a dma transfer, 284 * updating pointers. 285 */ --- 219 unchanged lines hidden (view full) --- 505#if 0 506 amt = sndbuf_getready(b); 507 if (sndbuf_getfree(bs) < amt) { 508 c->xruns++; 509 amt = sndbuf_getfree(bs); 510 } 511#endif 512 amt = sndbuf_getfree(bs); |
500 ret = (amt > 0) ? sndbuf_feed(b, bs, c, c->feeder, amt) : 0; | 513 ret = (amt > 0) ? sndbuf_feed(b, bs, c, c->feeder, amt) : ENOSPC; |
501 502 amt = sndbuf_getready(b); 503 if (amt > 0) { 504 c->xruns++; 505 sndbuf_dispose(b, NULL, amt); 506 } 507 508 if (sndbuf_getready(bs) > 0) --- 5 unchanged lines hidden (view full) --- 514void 515chn_rdupdate(struct pcm_channel *c) 516{ 517 int ret; 518 519 CHN_LOCKASSERT(c); 520 KASSERT(c->direction == PCMDIR_REC, ("chn_rdupdate on bad channel")); 521 | 514 515 amt = sndbuf_getready(b); 516 if (amt > 0) { 517 c->xruns++; 518 sndbuf_dispose(b, NULL, amt); 519 } 520 521 if (sndbuf_getready(bs) > 0) --- 5 unchanged lines hidden (view full) --- 527void 528chn_rdupdate(struct pcm_channel *c) 529{ 530 int ret; 531 532 CHN_LOCKASSERT(c); 533 KASSERT(c->direction == PCMDIR_REC, ("chn_rdupdate on bad channel")); 534 |
522 if ((c->flags & CHN_F_MAPPED) || CHN_STOPPED(c)) | 535 if ((c->flags & (CHN_F_MAPPED | CHN_F_VIRTUAL)) || CHN_STOPPED(c)) |
523 return; 524 chn_trigger(c, PCMTRIG_EMLDMARD); 525 chn_dmaupdate(c); 526 ret = chn_rdfeed(c); 527 DEB(if (ret) 528 printf("chn_rdfeed: %d\n", ret);) 529 530} --- 109 unchanged lines hidden (view full) --- 640 } else { 641 struct snd_dbuf *pb; 642 643 pb = BUF_PARENT(c, b); 644 i = sndbuf_xbytes(sndbuf_getready(bs), bs, pb); 645 j = sndbuf_getbps(pb); 646 } 647 } | 536 return; 537 chn_trigger(c, PCMTRIG_EMLDMARD); 538 chn_dmaupdate(c); 539 ret = chn_rdfeed(c); 540 DEB(if (ret) 541 printf("chn_rdfeed: %d\n", ret);) 542 543} --- 109 unchanged lines hidden (view full) --- 653 } else { 654 struct snd_dbuf *pb; 655 656 pb = BUF_PARENT(c, b); 657 i = sndbuf_xbytes(sndbuf_getready(bs), bs, pb); 658 j = sndbuf_getbps(pb); 659 } 660 } |
648 if (snd_verbose > 3 && SLIST_EMPTY(&c->children)) | 661 if (snd_verbose > 3 && CHN_EMPTY(c, children)) |
649 printf("%s: %s (%s) threshold i=%d j=%d\n", 650 __func__, CHN_DIRSTR(c), 651 (c->flags & CHN_F_VIRTUAL) ? "virtual" : "hardware", 652 i, j); 653 } 654 655 if (i >= j) { 656 c->flags |= CHN_F_TRIGGERED; --- 432 unchanged lines hidden (view full) --- 1089 1090 if (chn_timeout < CHN_TIMEOUT_MIN || chn_timeout > CHN_TIMEOUT_MAX) 1091 chn_timeout = CHN_TIMEOUT; 1092 1093 chn_lockinit(c, dir); 1094 1095 b = NULL; 1096 bs = NULL; | 662 printf("%s: %s (%s) threshold i=%d j=%d\n", 663 __func__, CHN_DIRSTR(c), 664 (c->flags & CHN_F_VIRTUAL) ? "virtual" : "hardware", 665 i, j); 666 } 667 668 if (i >= j) { 669 c->flags |= CHN_F_TRIGGERED; --- 432 unchanged lines hidden (view full) --- 1102 1103 if (chn_timeout < CHN_TIMEOUT_MIN || chn_timeout > CHN_TIMEOUT_MAX) 1104 chn_timeout = CHN_TIMEOUT; 1105 1106 chn_lockinit(c, dir); 1107 1108 b = NULL; 1109 bs = NULL; |
1110 CHN_INIT(c, children); 1111 CHN_INIT(c, children.busy); |
|
1097 c->devinfo = NULL; 1098 c->feeder = NULL; 1099 c->latency = -1; 1100 c->timeout = 1; 1101 1102 ret = ENOMEM; 1103 b = sndbuf_create(c->dev, c->name, "primary", c); 1104 if (b == NULL) --- 83 unchanged lines hidden (view full) --- 1188} 1189 1190int 1191chn_kill(struct pcm_channel *c) 1192{ 1193 struct snd_dbuf *b = c->bufhard; 1194 struct snd_dbuf *bs = c->bufsoft; 1195 | 1112 c->devinfo = NULL; 1113 c->feeder = NULL; 1114 c->latency = -1; 1115 c->timeout = 1; 1116 1117 ret = ENOMEM; 1118 b = sndbuf_create(c->dev, c->name, "primary", c); 1119 if (b == NULL) --- 83 unchanged lines hidden (view full) --- 1203} 1204 1205int 1206chn_kill(struct pcm_channel *c) 1207{ 1208 struct snd_dbuf *b = c->bufhard; 1209 struct snd_dbuf *bs = c->bufsoft; 1210 |
1196 if (CHN_STARTED(c)) | 1211 if (CHN_STARTED(c)) { 1212 CHN_LOCK(c); |
1197 chn_trigger(c, PCMTRIG_ABORT); | 1213 chn_trigger(c, PCMTRIG_ABORT); |
1198 while (chn_removefeeder(c) == 0); | 1214 CHN_UNLOCK(c); 1215 } 1216 while (chn_removefeeder(c) == 0) 1217 ; |
1199 if (CHANNEL_FREE(c->methods, c->devinfo)) 1200 sndbuf_free(b); 1201 c->flags |= CHN_F_DEAD; 1202 sndbuf_destroy(bs); 1203 sndbuf_destroy(b); 1204 chn_lockdestroy(c); 1205 return 0; 1206} --- 316 unchanged lines hidden (view full) --- 1523 CHN_UNLOCK(c); 1524 if (chn_usefrags == 0 || 1525 CHANNEL_SETFRAGMENTS(c->methods, c->devinfo, 1526 hblksz, hblkcnt) < 1) 1527 sndbuf_setblksz(b, CHANNEL_SETBLOCKSIZE(c->methods, 1528 c->devinfo, hblksz)); 1529 CHN_LOCK(c); 1530 | 1218 if (CHANNEL_FREE(c->methods, c->devinfo)) 1219 sndbuf_free(b); 1220 c->flags |= CHN_F_DEAD; 1221 sndbuf_destroy(bs); 1222 sndbuf_destroy(b); 1223 chn_lockdestroy(c); 1224 return 0; 1225} --- 316 unchanged lines hidden (view full) --- 1542 CHN_UNLOCK(c); 1543 if (chn_usefrags == 0 || 1544 CHANNEL_SETFRAGMENTS(c->methods, c->devinfo, 1545 hblksz, hblkcnt) < 1) 1546 sndbuf_setblksz(b, CHANNEL_SETBLOCKSIZE(c->methods, 1547 c->devinfo, hblksz)); 1548 CHN_LOCK(c); 1549 |
1531 if (!SLIST_EMPTY(&c->children)) { | 1550 if (!CHN_EMPTY(c, children)) { |
1532 sblksz = round_blksz( 1533 sndbuf_xbytes(sndbuf_getsize(b) >> 1, b, bs), 1534 sndbuf_getbps(bs)); 1535 sblkcnt = 2; 1536 limit = 0; 1537 } else if (limit != 0) 1538 limit = sndbuf_xbytes(sndbuf_getsize(b), b, bs); 1539 --- 205 unchanged lines hidden (view full) --- 1745} 1746 1747int 1748chn_trigger(struct pcm_channel *c, int go) 1749{ 1750#ifdef DEV_ISA 1751 struct snd_dbuf *b = c->bufhard; 1752#endif | 1551 sblksz = round_blksz( 1552 sndbuf_xbytes(sndbuf_getsize(b) >> 1, b, bs), 1553 sndbuf_getbps(bs)); 1554 sblkcnt = 2; 1555 limit = 0; 1556 } else if (limit != 0) 1557 limit = sndbuf_xbytes(sndbuf_getsize(b), b, bs); 1558 --- 205 unchanged lines hidden (view full) --- 1764} 1765 1766int 1767chn_trigger(struct pcm_channel *c, int go) 1768{ 1769#ifdef DEV_ISA 1770 struct snd_dbuf *b = c->bufhard; 1771#endif |
1772 struct snddev_info *d = c->parentsnddev; |
|
1753 int ret; 1754 1755 CHN_LOCKASSERT(c); 1756#ifdef DEV_ISA 1757 if (SND_DMA(b) && (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD)) 1758 sndbuf_dmabounce(b); 1759#endif | 1773 int ret; 1774 1775 CHN_LOCKASSERT(c); 1776#ifdef DEV_ISA 1777 if (SND_DMA(b) && (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD)) 1778 sndbuf_dmabounce(b); 1779#endif |
1780 if ((go == PCMTRIG_START || go == PCMTRIG_STOP || 1781 go == PCMTRIG_ABORT) && go == c->trigger) 1782 return 0; 1783 |
|
1760 ret = CHANNEL_TRIGGER(c->methods, c->devinfo, go); 1761 | 1784 ret = CHANNEL_TRIGGER(c->methods, c->devinfo, go); 1785 |
1786 if (ret == 0) { 1787 switch (go) { 1788 case PCMTRIG_START: 1789 if (snd_verbose > 3) 1790 device_printf(c->dev, 1791 "%s() %s: calling go=0x%08x , " 1792 "prev=0x%08x\n", __func__, c->name, go, 1793 c->trigger); 1794 if (c->trigger != PCMTRIG_START) { 1795 c->trigger = go; 1796 CHN_UNLOCK(c); 1797 pcm_lock(d); 1798 CHN_INSERT_HEAD(d, c, channels.pcm.busy); 1799 pcm_unlock(d); 1800 CHN_LOCK(c); 1801 } 1802 break; 1803 case PCMTRIG_STOP: 1804 case PCMTRIG_ABORT: 1805 if (snd_verbose > 3) 1806 device_printf(c->dev, 1807 "%s() %s: calling go=0x%08x , " 1808 "prev=0x%08x\n", __func__, c->name, go, 1809 c->trigger); 1810 if (c->trigger == PCMTRIG_START) { 1811 c->trigger = go; 1812 CHN_UNLOCK(c); 1813 pcm_lock(d); 1814 CHN_REMOVE(d, c, channels.pcm.busy); 1815 pcm_unlock(d); 1816 CHN_LOCK(c); 1817 } 1818 break; 1819 default: 1820 break; 1821 } 1822 } 1823 |
|
1762 return ret; 1763} 1764 1765/** 1766 * @brief Queries sound driver for sample-aligned hardware buffer pointer index 1767 * 1768 * This function obtains the hardware pointer location, then aligns it to 1769 * the current bytes-per-sample value before returning. (E.g., a channel --- 65 unchanged lines hidden (view full) --- 1835 1836 CHN_LOCKASSERT(c); 1837 while (chn_removefeeder(c) == 0) 1838 ; 1839 KASSERT((c->feeder == NULL), ("feeder chain not empty")); 1840 1841 c->align = sndbuf_getalign(c->bufsoft); 1842 | 1824 return ret; 1825} 1826 1827/** 1828 * @brief Queries sound driver for sample-aligned hardware buffer pointer index 1829 * 1830 * This function obtains the hardware pointer location, then aligns it to 1831 * the current bytes-per-sample value before returning. (E.g., a channel --- 65 unchanged lines hidden (view full) --- 1897 1898 CHN_LOCKASSERT(c); 1899 while (chn_removefeeder(c) == 0) 1900 ; 1901 KASSERT((c->feeder == NULL), ("feeder chain not empty")); 1902 1903 c->align = sndbuf_getalign(c->bufsoft); 1904 |
1843 if (SLIST_EMPTY(&c->children)) { | 1905 if (CHN_EMPTY(c, children) || c->direction == PCMDIR_REC) { 1906 /* 1907 * Virtual rec need this. 1908 */ |
1844 fc = feeder_getclass(NULL); 1845 KASSERT(fc != NULL, ("can't find root feeder")); 1846 1847 err = chn_addfeeder(c, fc, NULL); 1848 if (err) { 1849 DEB(printf("can't add root feeder, err %d\n", err)); 1850 1851 return err; 1852 } 1853 c->feeder->desc->out = c->format; | 1909 fc = feeder_getclass(NULL); 1910 KASSERT(fc != NULL, ("can't find root feeder")); 1911 1912 err = chn_addfeeder(c, fc, NULL); 1913 if (err) { 1914 DEB(printf("can't add root feeder, err %d\n", err)); 1915 1916 return err; 1917 } 1918 c->feeder->desc->out = c->format; |
1854 } else { | 1919 } else if (c->direction == PCMDIR_PLAY) { |
1855 if (c->flags & CHN_F_HAS_VCHAN) { 1856 desc.type = FEEDER_MIXER; 1857 desc.in = c->format; 1858 } else { 1859 DEB(printf("can't decide which feeder type to use!\n")); 1860 return EOPNOTSUPP; 1861 } 1862 desc.out = c->format; --- 6 unchanged lines hidden (view full) --- 1869 } 1870 1871 err = chn_addfeeder(c, fc, &desc); 1872 if (err) { 1873 DEB(printf("can't add vchan feeder, err %d\n", err)); 1874 1875 return err; 1876 } | 1920 if (c->flags & CHN_F_HAS_VCHAN) { 1921 desc.type = FEEDER_MIXER; 1922 desc.in = c->format; 1923 } else { 1924 DEB(printf("can't decide which feeder type to use!\n")); 1925 return EOPNOTSUPP; 1926 } 1927 desc.out = c->format; --- 6 unchanged lines hidden (view full) --- 1934 } 1935 1936 err = chn_addfeeder(c, fc, &desc); 1937 if (err) { 1938 DEB(printf("can't add vchan feeder, err %d\n", err)); 1939 1940 return err; 1941 } |
1877 } | 1942 } else 1943 return EOPNOTSUPP; 1944 |
1878 c->feederflags &= ~(1 << FEEDER_VOLUME); 1879 if (c->direction == PCMDIR_PLAY && 1880 !(c->flags & CHN_F_VIRTUAL) && c->parentsnddev && 1881 (c->parentsnddev->flags & SD_F_SOFTPCMVOL) && 1882 c->parentsnddev->mixer_dev) 1883 c->feederflags |= 1 << FEEDER_VOLUME; 1884 if (!(c->flags & CHN_F_VIRTUAL) && c->parentsnddev && 1885 ((c->direction == PCMDIR_PLAY && --- 83 unchanged lines hidden (view full) --- 1969 tmp[1] = 0; 1970 hwfmt = chn_fmtchain(c, tmp); 1971 } else 1972 hwfmt = chn_fmtchain(c, fmtlist); 1973 1974 if (hwfmt == 0 || !fmtvalid(hwfmt, fmtlist)) { 1975 DEB(printf("Invalid hardware format: 0x%08x\n", hwfmt)); 1976 return ENODEV; | 1945 c->feederflags &= ~(1 << FEEDER_VOLUME); 1946 if (c->direction == PCMDIR_PLAY && 1947 !(c->flags & CHN_F_VIRTUAL) && c->parentsnddev && 1948 (c->parentsnddev->flags & SD_F_SOFTPCMVOL) && 1949 c->parentsnddev->mixer_dev) 1950 c->feederflags |= 1 << FEEDER_VOLUME; 1951 if (!(c->flags & CHN_F_VIRTUAL) && c->parentsnddev && 1952 ((c->direction == PCMDIR_PLAY && --- 83 unchanged lines hidden (view full) --- 2036 tmp[1] = 0; 2037 hwfmt = chn_fmtchain(c, tmp); 2038 } else 2039 hwfmt = chn_fmtchain(c, fmtlist); 2040 2041 if (hwfmt == 0 || !fmtvalid(hwfmt, fmtlist)) { 2042 DEB(printf("Invalid hardware format: 0x%08x\n", hwfmt)); 2043 return ENODEV; |
2044 } else if (c->direction == PCMDIR_REC && !CHN_EMPTY(c, children)) { 2045 /* 2046 * Kind of awkward. This whole "MIXER" concept need a 2047 * rethinking, I guess :) . Recording is the inverse 2048 * of Playback, which is why we push mixer vchan down here. 2049 */ 2050 if (c->flags & CHN_F_HAS_VCHAN) { 2051 desc.type = FEEDER_MIXER; 2052 desc.in = c->format; 2053 } else 2054 return EOPNOTSUPP; 2055 desc.out = c->format; 2056 desc.flags = 0; 2057 fc = feeder_getclass(&desc); 2058 if (fc == NULL) 2059 return EOPNOTSUPP; 2060 2061 err = chn_addfeeder(c, fc, &desc); 2062 if (err != 0) 2063 return err; |
|
1977 } 1978 1979 sndbuf_setfmt(c->bufhard, hwfmt); 1980 1981 if ((flags & (1 << FEEDER_VOLUME))) { 1982 u_int32_t parent = SOUND_MIXER_NONE; 1983 int vol, left, right; 1984 --- 30 unchanged lines hidden (view full) --- 2015 } 2016 2017 return 0; 2018} 2019 2020int 2021chn_notify(struct pcm_channel *c, u_int32_t flags) 2022{ | 2064 } 2065 2066 sndbuf_setfmt(c->bufhard, hwfmt); 2067 2068 if ((flags & (1 << FEEDER_VOLUME))) { 2069 u_int32_t parent = SOUND_MIXER_NONE; 2070 int vol, left, right; 2071 --- 30 unchanged lines hidden (view full) --- 2102 } 2103 2104 return 0; 2105} 2106 2107int 2108chn_notify(struct pcm_channel *c, u_int32_t flags) 2109{ |
2023 struct pcmchan_children *pce; 2024 struct pcm_channel *child; | |
2025 int run; 2026 2027 CHN_LOCK(c); 2028 | 2110 int run; 2111 2112 CHN_LOCK(c); 2113 |
2029 if (SLIST_EMPTY(&c->children)) { | 2114 if (CHN_EMPTY(c, children)) { |
2030 CHN_UNLOCK(c); 2031 return ENODEV; 2032 } 2033 2034 run = (CHN_STARTED(c)) ? 1 : 0; 2035 /* 2036 * if the hwchan is running, we can't change its rate, format or 2037 * blocksize --- 21 unchanged lines hidden (view full) --- 2059 if (flags & CHN_N_BLOCKSIZE) { 2060 /* 2061 * Set to default latency profile 2062 */ 2063 chn_setlatency(c, chn_latency); 2064 } 2065 if (flags & CHN_N_TRIGGER) { 2066 int nrun; | 2115 CHN_UNLOCK(c); 2116 return ENODEV; 2117 } 2118 2119 run = (CHN_STARTED(c)) ? 1 : 0; 2120 /* 2121 * if the hwchan is running, we can't change its rate, format or 2122 * blocksize --- 21 unchanged lines hidden (view full) --- 2144 if (flags & CHN_N_BLOCKSIZE) { 2145 /* 2146 * Set to default latency profile 2147 */ 2148 chn_setlatency(c, chn_latency); 2149 } 2150 if (flags & CHN_N_TRIGGER) { 2151 int nrun; |
2067 /* 2068 * scan the children, and figure out if any are running 2069 * if so, we need to be running, otherwise we need to be stopped 2070 * if we aren't in our target sstate, move to it 2071 */ 2072 nrun = 0; 2073 SLIST_FOREACH(pce, &c->children, link) { 2074 child = pce->channel; 2075 CHN_LOCK(child); 2076 nrun = CHN_STARTED(child); 2077 CHN_UNLOCK(child); 2078 if (nrun) 2079 break; 2080 } | 2152 2153 nrun = CHN_EMPTY(c, children.busy) ? 0 : 1; |
2081 if (nrun && !run) 2082 chn_start(c, 1); 2083 if (!nrun && run) 2084 chn_abort(c); 2085 } 2086 CHN_UNLOCK(c); 2087 return 0; 2088} --- 92 unchanged lines hidden --- | 2154 if (nrun && !run) 2155 chn_start(c, 1); 2156 if (!nrun && run) 2157 chn_abort(c); 2158 } 2159 CHN_UNLOCK(c); 2160 return 0; 2161} --- 92 unchanged lines hidden --- |