buffer.c (160439) | buffer.c (162588) |
---|---|
1/*- 2 * Copyright (c) 1999 Cameron Grant <cg@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 14 unchanged lines hidden (view full) --- 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <dev/sound/pcm/sound.h> 28 29#include "feeder_if.h" 30 | 1/*- 2 * Copyright (c) 1999 Cameron Grant <cg@freebsd.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 14 unchanged lines hidden (view full) --- 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <dev/sound/pcm/sound.h> 28 29#include "feeder_if.h" 30 |
31SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pcm/buffer.c 160439 2006-07-17 17:43:06Z netchild $"); | 31SND_DECLARE_FILE("$FreeBSD: head/sys/dev/sound/pcm/buffer.c 162588 2006-09-23 20:45:47Z netchild $"); |
32 33struct snd_dbuf * 34sndbuf_create(device_t dev, char *drv, char *desc, struct pcm_channel *channel) 35{ 36 struct snd_dbuf *b; 37 38 b = malloc(sizeof(*b), M_DEVBUF, M_WAITOK | M_ZERO); 39 snprintf(b->name, SNDBUF_NAMELEN, "%s:%s", drv, desc); --- 72 unchanged lines hidden (view full) --- 112 113void 114sndbuf_free(struct snd_dbuf *b) 115{ 116 if (b->tmpbuf) 117 free(b->tmpbuf, M_DEVBUF); 118 b->tmpbuf = NULL; 119 | 32 33struct snd_dbuf * 34sndbuf_create(device_t dev, char *drv, char *desc, struct pcm_channel *channel) 35{ 36 struct snd_dbuf *b; 37 38 b = malloc(sizeof(*b), M_DEVBUF, M_WAITOK | M_ZERO); 39 snprintf(b->name, SNDBUF_NAMELEN, "%s:%s", drv, desc); --- 72 unchanged lines hidden (view full) --- 112 113void 114sndbuf_free(struct snd_dbuf *b) 115{ 116 if (b->tmpbuf) 117 free(b->tmpbuf, M_DEVBUF); 118 b->tmpbuf = NULL; 119 |
120 if (b->shadbuf) 121 free(b->shadbuf, M_DEVBUF); 122 b->shadbuf = NULL; 123 b->sl = 0; 124 |
|
120 if (b->dmamap) 121 bus_dmamap_unload(b->dmatag, b->dmamap); 122 123 if (b->dmamap && b->buf) 124 bus_dmamem_free(b->dmatag, b->buf, b->dmamap); 125 b->dmamap = NULL; 126 b->buf = NULL; 127} --- 35 unchanged lines hidden (view full) --- 163 chn_unlock(b->channel); 164 return 0; 165} 166 167int 168sndbuf_remalloc(struct snd_dbuf *b, unsigned int blkcnt, unsigned int blksz) 169{ 170 u_int8_t *buf, *tmpbuf, *f1, *f2; | 125 if (b->dmamap) 126 bus_dmamap_unload(b->dmatag, b->dmamap); 127 128 if (b->dmamap && b->buf) 129 bus_dmamem_free(b->dmatag, b->buf, b->dmamap); 130 b->dmamap = NULL; 131 b->buf = NULL; 132} --- 35 unchanged lines hidden (view full) --- 168 chn_unlock(b->channel); 169 return 0; 170} 171 172int 173sndbuf_remalloc(struct snd_dbuf *b, unsigned int blkcnt, unsigned int blksz) 174{ 175 u_int8_t *buf, *tmpbuf, *f1, *f2; |
176 u_int8_t *shadbuf, *f3; |
|
171 unsigned int bufsize; 172 int ret; 173 174 if (blkcnt < 2 || blksz < 16) 175 return EINVAL; 176 177 bufsize = blksz * blkcnt; 178 --- 5 unchanged lines hidden (view full) --- 184 } 185 186 tmpbuf = malloc(bufsize, M_DEVBUF, M_WAITOK); 187 if (tmpbuf == NULL) { 188 free(buf, M_DEVBUF); 189 ret = ENOMEM; 190 goto out; 191 } | 177 unsigned int bufsize; 178 int ret; 179 180 if (blkcnt < 2 || blksz < 16) 181 return EINVAL; 182 183 bufsize = blksz * blkcnt; 184 --- 5 unchanged lines hidden (view full) --- 190 } 191 192 tmpbuf = malloc(bufsize, M_DEVBUF, M_WAITOK); 193 if (tmpbuf == NULL) { 194 free(buf, M_DEVBUF); 195 ret = ENOMEM; 196 goto out; 197 } |
198 199 shadbuf = malloc(bufsize, M_DEVBUF, M_WAITOK); 200 if (shadbuf == NULL) { 201 free(buf, M_DEVBUF); 202 free(tmpbuf, M_DEVBUF); 203 ret = ENOMEM; 204 goto out; 205 } 206 |
|
192 chn_lock(b->channel); 193 194 b->blkcnt = blkcnt; 195 b->blksz = blksz; 196 b->bufsize = bufsize; 197 b->maxsize = bufsize; 198 f1 = b->buf; 199 f2 = b->tmpbuf; 200 b->buf = buf; 201 b->tmpbuf = tmpbuf; | 207 chn_lock(b->channel); 208 209 b->blkcnt = blkcnt; 210 b->blksz = blksz; 211 b->bufsize = bufsize; 212 b->maxsize = bufsize; 213 f1 = b->buf; 214 f2 = b->tmpbuf; 215 b->buf = buf; 216 b->tmpbuf = tmpbuf; |
217 f3 = b->shadbuf; 218 b->shadbuf = shadbuf; 219 b->sl = bufsize; |
|
202 203 sndbuf_reset(b); 204 205 chn_unlock(b->channel); 206 if (f1) 207 free(f1, M_DEVBUF); 208 if (f2) 209 free(f2, M_DEVBUF); | 220 221 sndbuf_reset(b); 222 223 chn_unlock(b->channel); 224 if (f1) 225 free(f1, M_DEVBUF); 226 if (f2) 227 free(f2, M_DEVBUF); |
228 if (f3) 229 free(f3, M_DEVBUF); |
|
210 211 ret = 0; 212out: 213 chn_lock(b->channel); 214 return ret; 215} 216 | 230 231 ret = 0; 232out: 233 chn_lock(b->channel); 234 return ret; 235} 236 |
237/** 238 * @brief Zero out space in buffer free area 239 * 240 * This function clears a chunk of @c length bytes in the buffer free area 241 * (i.e., where the next write will be placed). 242 * 243 * @param b buffer context 244 * @param length number of bytes to blank 245 */ |
|
217void 218sndbuf_clear(struct snd_dbuf *b, unsigned int length) 219{ 220 int i; 221 u_char data, *p; 222 223 if (length == 0) 224 return; --- 11 unchanged lines hidden (view full) --- 236 p[i] = data; 237 length--; 238 i++; 239 if (i >= b->bufsize) 240 i = 0; 241 } 242} 243 | 246void 247sndbuf_clear(struct snd_dbuf *b, unsigned int length) 248{ 249 int i; 250 u_char data, *p; 251 252 if (length == 0) 253 return; --- 11 unchanged lines hidden (view full) --- 265 p[i] = data; 266 length--; 267 i++; 268 if (i >= b->bufsize) 269 i = 0; 270 } 271} 272 |
273/** 274 * @brief Zap buffer contents, resetting "ready area" fields 275 * 276 * @param b buffer context 277 */ |
|
244void 245sndbuf_fillsilence(struct snd_dbuf *b) 246{ 247 int i; 248 u_char data, *p; 249 250 if (b->fmt & AFMT_SIGNED) 251 data = 0x00; 252 else 253 data = 0x80; 254 255 i = 0; 256 p = sndbuf_getbuf(b); 257 while (i < b->bufsize) 258 p[i++] = data; 259 b->rp = 0; 260 b->rl = b->bufsize; 261} 262 | 278void 279sndbuf_fillsilence(struct snd_dbuf *b) 280{ 281 int i; 282 u_char data, *p; 283 284 if (b->fmt & AFMT_SIGNED) 285 data = 0x00; 286 else 287 data = 0x80; 288 289 i = 0; 290 p = sndbuf_getbuf(b); 291 while (i < b->bufsize) 292 p[i++] = data; 293 b->rp = 0; 294 b->rl = b->bufsize; 295} 296 |
297/** 298 * @brief Reset buffer w/o flushing statistics 299 * 300 * This function just zeroes out buffer contents and sets the "ready length" 301 * to zero. This was originally to facilitate minimal playback interruption 302 * (i.e., dropped samples) in SNDCTL_DSP_SILENCE/SKIP ioctls. 303 * 304 * @param b buffer context 305 */ |
|
263void | 306void |
307sndbuf_softreset(struct snd_dbuf *b) 308{ 309 b->rl = 0; 310 if (b->buf && b->bufsize > 0) 311 sndbuf_clear(b, b->bufsize); 312} 313 314void |
|
264sndbuf_reset(struct snd_dbuf *b) 265{ 266 b->hp = 0; 267 b->rp = 0; 268 b->rl = 0; 269 b->dl = 0; 270 b->prev_total = 0; 271 b->total = 0; 272 b->xrun = 0; 273 if (b->buf && b->bufsize > 0) 274 sndbuf_clear(b, b->bufsize); | 315sndbuf_reset(struct snd_dbuf *b) 316{ 317 b->hp = 0; 318 b->rp = 0; 319 b->rl = 0; 320 b->dl = 0; 321 b->prev_total = 0; 322 b->total = 0; 323 b->xrun = 0; 324 if (b->buf && b->bufsize > 0) 325 sndbuf_clear(b, b->bufsize); |
326 sndbuf_clearshadow(b); |
|
275} 276 277u_int32_t 278sndbuf_getfmt(struct snd_dbuf *b) 279{ 280 return b->fmt; 281} 282 --- 205 unchanged lines hidden (view full) --- 488{ 489 SNDBUF_LOCKASSERT(b); 490 491 b->prev_total = b->total; 492} 493 494/************************************************************/ 495 | 327} 328 329u_int32_t 330sndbuf_getfmt(struct snd_dbuf *b) 331{ 332 return b->fmt; 333} 334 --- 205 unchanged lines hidden (view full) --- 540{ 541 SNDBUF_LOCKASSERT(b); 542 543 b->prev_total = b->total; 544} 545 546/************************************************************/ 547 |
548/** 549 * @brief Acquire buffer space to extend ready area 550 * 551 * This function extends the ready area length by @c count bytes, and may 552 * optionally copy samples from another location stored in @c from. The 553 * counter @c snd_dbuf::total is also incremented by @c count bytes. 554 * 555 * @param b audio buffer 556 * @param from sample source (optional) 557 * @param count number of bytes to acquire 558 * 559 * @retval 0 Unconditional 560 */ |
|
496int 497sndbuf_acquire(struct snd_dbuf *b, u_int8_t *from, unsigned int count) 498{ 499 int l; 500 501 KASSERT(count <= sndbuf_getfree(b), ("%s: count %d > free %d", __func__, count, sndbuf_getfree(b))); 502 KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d", __func__, b->rl)); 503 b->total += count; --- 7 unchanged lines hidden (view full) --- 511 } 512 } else 513 b->rl += count; 514 KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d, count %d", __func__, b->rl, count)); 515 516 return 0; 517} 518 | 561int 562sndbuf_acquire(struct snd_dbuf *b, u_int8_t *from, unsigned int count) 563{ 564 int l; 565 566 KASSERT(count <= sndbuf_getfree(b), ("%s: count %d > free %d", __func__, count, sndbuf_getfree(b))); 567 KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d", __func__, b->rl)); 568 b->total += count; --- 7 unchanged lines hidden (view full) --- 576 } 577 } else 578 b->rl += count; 579 KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d, count %d", __func__, b->rl, count)); 580 581 return 0; 582} 583 |
584/** 585 * @brief Dispose samples from channel buffer, increasing size of ready area 586 * 587 * This function discards samples from the supplied buffer by advancing the 588 * ready area start pointer and decrementing the ready area length. If 589 * @c to is not NULL, then the discard samples will be copied to the location 590 * it points to. 591 * 592 * @param b PCM channel sound buffer 593 * @param to destination buffer (optional) 594 * @param count number of bytes to discard 595 * 596 * @returns 0 unconditionally 597 */ |
|
519int 520sndbuf_dispose(struct snd_dbuf *b, u_int8_t *to, unsigned int count) 521{ 522 int l; 523 524 KASSERT(count <= sndbuf_getready(b), ("%s: count %d > ready %d", __func__, count, sndbuf_getready(b))); 525 KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d", __func__, b->rl)); 526 if (to != NULL) { --- 60 unchanged lines hidden (view full) --- 587void 588sndbuf_setflags(struct snd_dbuf *b, u_int32_t flags, int on) 589{ 590 b->flags &= ~flags; 591 if (on) 592 b->flags |= flags; 593} 594 | 598int 599sndbuf_dispose(struct snd_dbuf *b, u_int8_t *to, unsigned int count) 600{ 601 int l; 602 603 KASSERT(count <= sndbuf_getready(b), ("%s: count %d > ready %d", __func__, count, sndbuf_getready(b))); 604 KASSERT((b->rl >= 0) && (b->rl <= b->bufsize), ("%s: b->rl invalid %d", __func__, b->rl)); 605 if (to != NULL) { --- 60 unchanged lines hidden (view full) --- 666void 667sndbuf_setflags(struct snd_dbuf *b, u_int32_t flags, int on) 668{ 669 b->flags &= ~flags; 670 if (on) 671 b->flags |= flags; 672} 673 |
674/** 675 * @brief Clear the shadow buffer by filling with samples equal to zero. 676 * 677 * @param b buffer to clear 678 */ 679void 680sndbuf_clearshadow(struct snd_dbuf *b) 681{ 682 KASSERT(b != NULL, ("b is a null pointer")); 683 KASSERT(b->sl >= 0, ("illegal shadow length")); 684 685 if ((b->shadbuf != NULL) && (b->sl > 0)) { 686 if (b->fmt & AFMT_SIGNED) 687 memset(b->shadbuf, 0x00, b->sl); 688 else 689 memset(b->shadbuf, 0x80, b->sl); 690 } 691} 692 693#ifdef OSSV4_EXPERIMENT 694/** 695 * @brief Return peak value from samples in buffer ready area. 696 * 697 * Peak ranges from 0-32767. If channel is monaural, most significant 16 698 * bits will be zero. For now, only expects to work with 1-2 channel 699 * buffers. 700 * 701 * @note Currently only operates with linear PCM formats. 702 * 703 * @param b buffer to analyze 704 * @param lpeak pointer to store left peak value 705 * @param rpeak pointer to store right peak value 706 */ 707void 708sndbuf_getpeaks(struct snd_dbuf *b, int *lp, int *rp) 709{ 710 u_int32_t lpeak, rpeak; 711 712 lpeak = 0; 713 rpeak = 0; 714 715 /** 716 * @todo fill this in later 717 */ 718} 719#endif |
|