Deleted Added
full compact
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