4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright (C) 4Front Technologies 1996-2008.
24 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
28 * Purpose: Audio format conversion routines used by audio.c
31 #include <sys/types.h>
33 #include <sys/sunddi.h>
34 #include <sys/audio/g711.h>
36 #include "audio_impl.h"
37 #include "audio_grc3.h"
39 extern uint_t audio_intrhz
;
42 * Note: In the function below, the division by the number of channels is
43 * probably fairly expensive. It turns out that we usually deal with stereo
44 * or mono data, so perhaps it would be useful to build custom versions of
45 * this function that only dealt with stereo or mono.
48 do_src(audio_stream_t
*sp
, void *p1
, void *p2
, int len
, int nchan
)
53 * Note that we presume that we are doing sample rate
54 * conversions on AUDIO_FORMAT_S24_NE, which means that have 4
55 * byte and 32-bit samples.
57 size
= sp
->s_cnv_max
/ 4; /* sample size is 4 */
60 for (ch
= 0; ch
< nchan
; ch
++) {
61 grc3_convert(sp
->s_src_state
[ch
], sp
->s_src_quality
,
62 p1
, p2
, len
, size
, nchan
, ch
);
64 return (((grc3state_t
*)sp
->s_src_state
[0])->outsz
);
68 setup_src(audio_stream_t
*sp
, int srate
, int trate
, int sch
, int tch
)
74 ASSERT(nch
<= AUDIO_MAX_CHANNELS
);
76 if (sp
->s_src_quality
< 1)
77 sp
->s_src_quality
= 1;
78 if (sp
->s_src_quality
> 5)
79 sp
->s_src_quality
= 5;
81 for (ch
= 0; ch
< nch
; ch
++) {
82 grc3_reset(sp
->s_src_state
[ch
]);
83 grc3_setup(sp
->s_src_state
[ch
], srate
, trate
);
88 cnv_srconly(audio_stream_t
*sp
, int len
)
90 void *src
= sp
->s_cnv_src
;
91 void *dst
= sp
->s_cnv_dst
;
94 * We must be using 24-bit native signed.
96 len
= do_src(sp
, src
, dst
, len
, sp
->s_cnv_src_nchan
);
105 cnv_s24oe(audio_stream_t
*sp
, int len
)
108 * Endian switch works in both directions. We do it in place.
110 int32_t *src
= sp
->s_cnv_src
;
112 for (int i
= len
* sp
->s_cnv_src_nchan
; i
; i
--) {
113 *src
= ddi_swap32(*src
);
122 cnv_from_s8(audio_stream_t
*sp
, int len
)
124 void *s
= sp
->s_cnv_src
;
125 void *d
= sp
->s_cnv_dst
;
129 for (int i
= len
* sp
->s_cnv_src_nchan
; i
; i
--)
130 *dst
++ = (*src
++) << 16;
138 cnv_from_u8(audio_stream_t
*sp
, int len
)
140 void *s
= sp
->s_cnv_src
;
141 void *d
= sp
->s_cnv_dst
;
145 for (int i
= len
* sp
->s_cnv_src_nchan
; i
; i
--)
146 *dst
++ = (int8_t)((*src
++) ^ 0x80) << 16;
154 cnv_from_ulaw(audio_stream_t
*sp
, int len
)
156 void *s
= sp
->s_cnv_src
;
157 void *d
= sp
->s_cnv_dst
;
161 for (int i
= len
* sp
->s_cnv_src_nchan
; i
; i
--) {
162 *dst
++ = _8ulaw2linear16
[(*src
++)] << 8;
170 cnv_from_alaw(audio_stream_t
*sp
, int len
)
172 void *s
= sp
->s_cnv_src
;
173 void *d
= sp
->s_cnv_dst
;
177 for (int i
= len
* sp
->s_cnv_src_nchan
; i
; i
--) {
178 *dst
++ = _8alaw2linear16
[(*src
++)] << 8;
186 cnv_from_s16ne(audio_stream_t
*sp
, int len
)
188 void *s
= sp
->s_cnv_src
;
189 void *d
= sp
->s_cnv_dst
;
193 for (int i
= len
* sp
->s_cnv_src_nchan
; i
; i
--)
194 *dst
++ = (*src
++) << 8;
202 cnv_from_s16oe(audio_stream_t
*sp
, int len
)
204 void *s
= sp
->s_cnv_src
;
205 void *d
= sp
->s_cnv_dst
;
209 for (int i
= len
* sp
->s_cnv_src_nchan
; i
; i
--)
210 *dst
++ = (int16_t)(ddi_swap16(*src
++)) << 8;
218 cnv_from_u16ne(audio_stream_t
*sp
, int len
)
220 void *s
= sp
->s_cnv_src
;
221 void *d
= sp
->s_cnv_dst
;
225 for (int i
= len
* sp
->s_cnv_src_nchan
; i
; i
--)
226 *dst
++ = (int16_t)((*src
++) ^ 0x8000) << 8;
234 cnv_from_u16oe(audio_stream_t
*sp
, int len
)
236 void *s
= sp
->s_cnv_src
;
237 void *d
= sp
->s_cnv_dst
;
241 for (int i
= len
* sp
->s_cnv_src_nchan
; i
; i
--)
242 *dst
++ = (int16_t)(ddi_swap16((*src
++) ^ 0x8000)) << 8;
250 cnv_from_s24p(audio_stream_t
*sp
, int len
)
252 void *s
= sp
->s_cnv_src
;
253 void *d
= sp
->s_cnv_dst
;
258 for (int i
= len
* sp
->s_cnv_src_nchan
; i
; i
--) {
259 /* NB: this is a little endian format */
261 tmp
|= (*src
++) << 8;
262 tmp
|= (*src
++) << 16;
272 cnv_from_s32ne(audio_stream_t
*sp
, int len
)
274 /* 32-bit conversions can be done in place */
275 int32_t *src
= sp
->s_cnv_src
;
277 for (int i
= len
* sp
->s_cnv_src_nchan
; i
; i
--, src
++)
284 cnv_from_s32oe(audio_stream_t
*sp
, int len
)
286 /* 32-bit conversions can be done in place */
287 int32_t *src
= sp
->s_cnv_src
;
289 for (int i
= len
* sp
->s_cnv_src_nchan
; i
; i
--, src
++)
290 *src
= (int32_t)(ddi_swap32(*src
)) >> 8;
296 * NB: All the destination format conversions use the same or fewer
297 * bytes as the 24-bit unpacked (32-bits used per sample), so we can
298 * convert all of them in place.
302 cnv_to_u8(audio_stream_t
*sp
, int len
)
304 int32_t *src
= sp
->s_cnv_src
;
305 uint8_t *dst
= (void *)src
;
307 for (int i
= len
* sp
->s_cnv_dst_nchan
; i
; i
--)
308 *dst
++ = (*src
++ >> 16) ^ 0x80;
314 cnv_to_s8(audio_stream_t
*sp
, int len
)
316 int32_t *src
= sp
->s_cnv_src
;
317 int8_t *dst
= (void *)src
;
319 for (int i
= len
* sp
->s_cnv_dst_nchan
; i
; i
--)
320 *dst
++ = *src
++ >> 16;
326 cnv_to_ulaw(audio_stream_t
*sp
, int len
)
328 int32_t *src
= sp
->s_cnv_src
;
329 uint8_t *dst
= (void *)src
;
331 for (int i
= len
* sp
->s_cnv_dst_nchan
; i
; i
--) {
334 idx
+= G711_ULAW_MIDPOINT
;
335 idx
&= 0x3fff; /* safety precaution */
336 *dst
++ = _14linear2ulaw8
[idx
];
343 cnv_to_alaw(audio_stream_t
*sp
, int len
)
345 int32_t *src
= sp
->s_cnv_src
;
346 uint8_t *dst
= (void *)src
;
348 for (int i
= len
* sp
->s_cnv_dst_nchan
; i
; i
--) {
351 idx
+= G711_ALAW_MIDPOINT
;
352 idx
&= 0x1fff; /* safety precaution */
353 *dst
++ = _13linear2alaw8
[idx
];
360 cnv_to_s16ne(audio_stream_t
*sp
, int len
)
362 int32_t *src
= sp
->s_cnv_src
;
363 int16_t *dst
= (void *)src
;
365 for (int i
= len
* sp
->s_cnv_dst_nchan
; i
; i
--)
366 *dst
++ = *src
++ >> 8;
372 cnv_to_s16oe(audio_stream_t
*sp
, int len
)
374 int32_t *src
= sp
->s_cnv_src
;
375 int16_t *dst
= (void *)src
;
377 for (int i
= len
* sp
->s_cnv_dst_nchan
; i
; i
--)
378 *dst
++ = ddi_swap16(*src
++ >> 8);
384 cnv_to_u16ne(audio_stream_t
*sp
, int len
)
386 int32_t *src
= sp
->s_cnv_src
;
387 uint16_t *dst
= (void *)src
;
389 for (int i
= len
* sp
->s_cnv_dst_nchan
; i
; i
--)
390 *dst
++ = (*src
++ >> 8) ^ 0x8000;
396 cnv_to_u16oe(audio_stream_t
*sp
, int len
)
398 int32_t *src
= sp
->s_cnv_src
;
399 uint16_t *dst
= (void *)src
;
401 for (int i
= len
* sp
->s_cnv_dst_nchan
; i
; i
--)
402 *dst
++ = ddi_swap16(*src
++ >> 8) ^ 0x8000;
408 cnv_to_s24p(audio_stream_t
*sp
, int len
)
410 int32_t *src
= sp
->s_cnv_src
;
411 uint8_t *dst
= (void *)src
;
414 for (int i
= len
* sp
->s_cnv_dst_nchan
; i
; i
--) {
415 /* NB: this is a little endian format */
418 *dst
++ = (d
>> 8) & 0xff;
419 *dst
++ = (d
>> 16) & 0xff;
426 cnv_to_s32ne(audio_stream_t
*sp
, int len
)
428 int32_t *src
= sp
->s_cnv_src
;
430 for (int i
= len
* sp
->s_cnv_dst_nchan
; i
; i
--, src
++)
437 cnv_to_s32oe(audio_stream_t
*sp
, int len
)
439 int32_t *src
= sp
->s_cnv_src
;
441 for (int i
= len
* sp
->s_cnv_dst_nchan
; i
; i
--, src
++)
442 *src
= ddi_swap32(*src
<< 8);
448 cnv_default(audio_stream_t
*sp
, int len
)
451 * Note that the formats were already preverified during
452 * select_converter, to ensure that only supported formats are
457 * Convert samples to 24 bit (32 bit lsb aligned) if
461 switch (sp
->s_cnv_src_format
) {
463 case AUDIO_FORMAT_U8
:
464 len
= cnv_from_u8(sp
, len
);
467 case AUDIO_FORMAT_S8
:
468 len
= cnv_from_s8(sp
, len
);
471 case AUDIO_FORMAT_ULAW
:
472 len
= cnv_from_ulaw(sp
, len
);
475 case AUDIO_FORMAT_ALAW
:
476 len
= cnv_from_alaw(sp
, len
);
479 case AUDIO_FORMAT_S16_NE
:
480 len
= cnv_from_s16ne(sp
, len
);
483 case AUDIO_FORMAT_S16_OE
:
484 len
= cnv_from_s16oe(sp
, len
);
487 case AUDIO_FORMAT_U16_NE
:
488 len
= cnv_from_u16ne(sp
, len
);
491 case AUDIO_FORMAT_U16_OE
:
492 len
= cnv_from_u16oe(sp
, len
);
495 case AUDIO_FORMAT_S32_NE
:
496 len
= cnv_from_s32ne(sp
, len
);
499 case AUDIO_FORMAT_S32_OE
:
500 len
= cnv_from_s32oe(sp
, len
);
503 case AUDIO_FORMAT_S24_OE
:
504 len
= cnv_s24oe(sp
, len
);
507 case AUDIO_FORMAT_S24_PACKED
:
508 len
= cnv_from_s24p(sp
, len
);
513 * If we aren't decreasing the number of channels, then do the
514 * SRC now. (We prefer to do SRC on the smaller number of channels.)
516 if (sp
->s_cnv_src_rate
!= sp
->s_cnv_dst_rate
&&
517 sp
->s_cnv_src_nchan
<= sp
->s_cnv_dst_nchan
) {
518 int32_t *src
= sp
->s_cnv_src
;
519 int32_t *dst
= sp
->s_cnv_dst
;
521 len
= do_src(sp
, src
, dst
, len
, sp
->s_cnv_src_nchan
);
528 * Convert between mono and stereo
531 if (sp
->s_cnv_src_nchan
!= sp
->s_cnv_dst_nchan
) {
532 int32_t *src
= sp
->s_cnv_src
;
533 int32_t *dst
= sp
->s_cnv_dst
;
534 int tc
= sp
->s_cnv_dst_nchan
;
535 int sc
= sp
->s_cnv_src_nchan
;
544 * Mono expansion. We expand into the stereo
545 * channel, and leave other channels silent.
547 for (i
= len
; i
; i
--) {
550 for (int j
= tc
- 2; j
> 0; j
--) {
556 } else if (sc
== 2 && tc
== 1) {
558 * Stereo -> mono. We do stereo separately to make
559 * the division fast (div by const 2 is just shift).
561 for (i
= len
; i
; i
--) {
563 * Take just the left channel sample,
564 * discard the right channel.
566 *dst
++ = *src
++; /* left */
571 * Multi channel conversions. We just copy the
572 * minimum number of channels.
575 /* Calculate number of frames */
579 /* Clear destination */
580 bzero(dst
, (len
* tc
* sizeof (int32_t)));
582 for (i
= len
; i
; i
--) {
585 for (c
= 0; c
< nc
; c
++)
595 * If we didn't do SRC pre-conversion, then do it now.
597 if (sp
->s_cnv_src_rate
!= sp
->s_cnv_dst_rate
&&
598 sp
->s_cnv_src_nchan
> sp
->s_cnv_dst_nchan
) {
600 int32_t *src
= sp
->s_cnv_src
;
601 int32_t *dst
= sp
->s_cnv_dst
;
603 len
= do_src(sp
, src
, dst
, len
, sp
->s_cnv_dst_nchan
);
610 * Finally convert samples from internal 24 bit format to target format
613 switch (sp
->s_cnv_dst_format
) {
614 case AUDIO_FORMAT_U8
:
615 len
= cnv_to_u8(sp
, len
);
618 case AUDIO_FORMAT_S8
:
619 len
= cnv_to_s8(sp
, len
);
622 case AUDIO_FORMAT_S16_NE
:
623 len
= cnv_to_s16ne(sp
, len
);
626 case AUDIO_FORMAT_S16_OE
:
627 len
= cnv_to_s16oe(sp
, len
);
630 case AUDIO_FORMAT_U16_NE
:
631 len
= cnv_to_u16ne(sp
, len
);
634 case AUDIO_FORMAT_U16_OE
:
635 len
= cnv_to_u16oe(sp
, len
);
638 case AUDIO_FORMAT_S24_OE
:
639 len
= cnv_s24oe(sp
, len
);
642 case AUDIO_FORMAT_S24_PACKED
:
643 len
= cnv_to_s24p(sp
, len
);
646 case AUDIO_FORMAT_S32_NE
:
647 len
= cnv_to_s32ne(sp
, len
);
650 case AUDIO_FORMAT_S32_OE
:
651 len
= cnv_to_s32oe(sp
, len
);
654 case AUDIO_FORMAT_ULAW
:
655 len
= cnv_to_ulaw(sp
, len
);
658 case AUDIO_FORMAT_ALAW
:
659 len
= cnv_to_alaw(sp
, len
);
666 static const struct audio_format_info
{
669 audio_cnv_func_t from
;
671 } audio_format_info
[] = {
672 { AUDIO_FORMAT_S8
, 1, cnv_from_s8
, cnv_to_s8
},
673 { AUDIO_FORMAT_U8
, 1, cnv_from_u8
, cnv_to_u8
},
674 { AUDIO_FORMAT_ULAW
, 1, cnv_from_ulaw
, cnv_to_ulaw
},
675 { AUDIO_FORMAT_ALAW
, 1, cnv_from_alaw
, cnv_to_alaw
},
676 { AUDIO_FORMAT_S16_NE
, 2, cnv_from_s16ne
, cnv_to_s16ne
},
677 { AUDIO_FORMAT_S16_OE
, 2, cnv_from_s16oe
, cnv_to_s16oe
},
678 { AUDIO_FORMAT_U16_NE
, 2, cnv_from_u16ne
, cnv_to_u16ne
},
679 { AUDIO_FORMAT_U16_OE
, 2, cnv_from_u16oe
, cnv_to_u16oe
},
680 { AUDIO_FORMAT_S32_NE
, 4, cnv_from_s32ne
, cnv_to_s32ne
},
681 { AUDIO_FORMAT_S32_OE
, 4, cnv_from_s32oe
, cnv_to_s32oe
},
683 /* 24-bit formats are "special" */
684 { AUDIO_FORMAT_S24_NE
, 4, NULL
, NULL
},
685 { AUDIO_FORMAT_S24_OE
, 4, cnv_s24oe
, cnv_s24oe
},
686 { AUDIO_FORMAT_S24_PACKED
, 3, cnv_from_s24p
, cnv_to_s24p
},
689 { AUDIO_FORMAT_NONE
, 0, NULL
, NULL
}
693 auimpl_format_setup(audio_stream_t
*sp
, audio_parms_t
*parms
, uint_t mask
)
695 audio_parms_t source
;
696 audio_parms_t target
;
697 audio_parms_t
*uparms
;
698 audio_cnv_func_t converter
= NULL
;
699 const struct audio_format_info
*info
;
700 int expand
= AUDIO_UNIT_EXPAND
;
701 unsigned cnv_sampsz
= sizeof (uint32_t);
703 boolean_t needsrc
= B_FALSE
;
710 ASSERT(mutex_owned(&sp
->s_lock
));
712 source
= sp
->s_cnv_src_parms
;
713 target
= sp
->s_cnv_dst_parms
;
715 if (sp
== &sp
->s_client
->c_ostream
) {
716 if (mask
& FORMAT_MSK_FMT
)
717 source
.p_format
= parms
->p_format
;
718 if (mask
& FORMAT_MSK_RATE
)
719 source
.p_rate
= parms
->p_rate
;
720 if (mask
& FORMAT_MSK_CHAN
)
721 source
.p_nchan
= parms
->p_nchan
;
724 if (mask
& FORMAT_MSK_FMT
)
725 target
.p_format
= parms
->p_format
;
726 if (mask
& FORMAT_MSK_RATE
)
727 target
.p_rate
= parms
->p_rate
;
728 if (mask
& FORMAT_MSK_CHAN
)
729 target
.p_nchan
= parms
->p_nchan
;
734 * At least one of the source or target are S24_NE.
736 * If we have a signed/native endian format, then pick an
737 * optimized converter. While at it, ensure that a valid
738 * format is selected.
740 * After this function executes, "info" will point to the
741 * format information for the user parameters.
743 if (source
.p_format
!= AUDIO_FORMAT_S24_NE
) {
744 for (info
= &audio_format_info
[0]; info
->sampsize
; info
++) {
745 if (source
.p_format
== info
->format
) {
746 converter
= info
->from
;
747 expand
*= sizeof (int32_t);
748 expand
/= info
->sampsize
;
749 /* save source frame size */
750 cnv_sampsz
= info
->sampsize
;
756 * Target format. Note that this case is also taken
757 * if we're operating on S24_NE data. In that case
758 * the converter will be NULL and expand will not be
761 for (info
= &audio_format_info
[0]; info
->sampsize
; info
++) {
762 if (target
.p_format
== info
->format
) {
763 converter
= info
->to
;
764 expand
*= info
->sampsize
;
765 expand
/= sizeof (int32_t);
770 if (info
->format
== AUDIO_FORMAT_NONE
) {
771 audio_dev_warn(sp
->s_client
->c_dev
, "invalid format selected");
776 ASSERT(info
->sampsize
);
778 if (source
.p_nchan
!= target
.p_nchan
) {
780 * if channels need conversion, then we must use the
783 converter
= cnv_default
;
784 expand
*= target
.p_nchan
;
785 expand
/= source
.p_nchan
;
788 if (source
.p_rate
!= target
.p_rate
) {
790 converter
= (converter
== NULL
) ? cnv_srconly
: cnv_default
;
792 expand
*= target
.p_rate
;
793 expand
/= source
.p_rate
;
797 * Figure out the size of the conversion buffer we need. We
798 * assume room for two full source fragments, which ought to
799 * be enough, even with rounding errors.
801 cnv_max
= 2 * (source
.p_rate
/ audio_intrhz
) *
802 cnv_sampsz
* source
.p_nchan
;
805 * If the conversion will cause us to expand fragments, then
806 * we need to increase cnv_max. Scale by AUDIO_UNIT_EXPAND to
807 * avoid rouding errors or losing bits when doing reducing
810 if (expand
> AUDIO_UNIT_EXPAND
) {
812 cnv_max
/= AUDIO_UNIT_EXPAND
;
815 framesz
= info
->sampsize
* uparms
->p_nchan
;
816 fragfr
= (uparms
->p_rate
/ audio_intrhz
);
817 fragbytes
= fragfr
* framesz
;
820 * We need to "tune" the buffer and fragment counts for some
821 * uses... OSS applications may like to configure a low
822 * latency, and they rely upon write() to block to prevent too
823 * much data from being queued up.
826 nfrags
= sp
->s_hintsz
/ fragbytes
;
827 } else if (sp
->s_hintfrags
) {
828 nfrags
= sp
->s_hintfrags
;
830 nfrags
= sp
->s_allocsz
/ fragbytes
;
834 * Now make sure that the hint works -- we need at least 2 fragments,
835 * and we need to fit within the room allocated to us.
840 while ((nfrags
* fragbytes
) > sp
->s_allocsz
) {
843 /* if the resulting configuration is invalid, note it */
849 * Now we need to allocate space.
851 * NB: Once the allocation succeeds, we must not fail. We are
852 * modifying the the stream settings and these changes must be
855 if (sp
->s_cnv_max
< cnv_max
) {
856 uint32_t *buf0
, *buf1
;
858 buf0
= kmem_alloc(cnv_max
, KM_NOSLEEP
);
859 buf1
= kmem_alloc(cnv_max
, KM_NOSLEEP
);
860 if ((buf0
== NULL
) || (buf1
== NULL
)) {
861 audio_dev_warn(sp
->s_client
->c_dev
,
862 "failed to allocate audio conversion buffer "
863 "(%u bytes)", cnv_max
);
865 kmem_free(buf0
, cnv_max
);
867 kmem_free(buf1
, cnv_max
);
872 kmem_free(sp
->s_cnv_buf0
, sp
->s_cnv_max
);
874 kmem_free(sp
->s_cnv_buf1
, sp
->s_cnv_max
);
876 sp
->s_cnv_buf0
= buf0
;
877 sp
->s_cnv_buf1
= buf1
;
878 sp
->s_cnv_max
= cnv_max
;
881 /* Set up the SRC state if we will be using SRC. */
883 setup_src(sp
, source
.p_rate
, target
.p_rate
,
884 source
.p_nchan
, target
.p_nchan
);
888 sp
->s_framesz
= framesz
;
889 sp
->s_fragfr
= fragfr
;
890 sp
->s_fragbytes
= fragbytes
;
891 sp
->s_nfrags
= nfrags
;
892 sp
->s_nframes
= nfrags
* fragfr
;
893 sp
->s_nbytes
= sp
->s_nframes
* framesz
;
894 *sp
->s_user_parms
= *uparms
;
895 sp
->s_converter
= converter
;
898 * Ensure that we toss any stale data -- probably wrong format.
899 * Note that as a consequence of this, all of the offsets and
900 * counters get reset. Clients should not rely on these values
901 * being preserved when changing formats.
903 * Its critical that we reset the indices, in particular,
904 * because not only will the data be the wrong format, but the
905 * indices themselves are quite possibly going to be invalid.
908 sp
->s_tail
= sp
->s_head
= 0;
909 sp
->s_tidx
= sp
->s_hidx
= 0;
915 auimpl_format_alloc(audio_stream_t
*sp
)
919 ASSERT(mutex_owned(&sp
->s_lock
));
920 for (i
= 0; i
< AUDIO_MAX_CHANNELS
; i
++) {
922 kmem_zalloc(sizeof (grc3state_t
), KM_NOSLEEP
);
923 if (sp
->s_src_state
[i
] == NULL
) {
924 audio_dev_warn(sp
->s_client
->c_dev
,
925 "unable to allocate SRC state structures");
933 auimpl_format_free(audio_stream_t
*sp
)
937 for (i
= 0; i
< AUDIO_MAX_CHANNELS
; i
++) {
938 if (sp
->s_src_state
[i
] != NULL
) {
939 kmem_free(sp
->s_src_state
[i
], sizeof (grc3state_t
));
940 sp
->s_src_state
[i
] = NULL
;