Thu Jan 2 09:18:15 2020 UTC ()
Pull up following revision(s) (requested by isaki in ticket #593):

	sys/dev/audio/audio.c: revision 1.34
	sys/dev/audio/audio.c: revision 1.35

Use M_WAITOK instead of M_NOWAIT.
These allocations don't require NOWAIT constraints.

Will fix PR kern/54796.

 -

Improve and simplify around audio_realloc().


(martin)
diff -r1.28.2.4 -r1.28.2.5 src/sys/dev/audio/audio.c

cvs diff -r1.28.2.4 -r1.28.2.5 src/sys/dev/audio/audio.c (expand / switch to unified diff)

--- src/sys/dev/audio/audio.c 2019/11/19 12:58:29 1.28.2.4
+++ src/sys/dev/audio/audio.c 2020/01/02 09:18:15 1.28.2.5
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: audio.c,v 1.28.2.4 2019/11/19 12:58:29 martin Exp $ */ 1/* $NetBSD: audio.c,v 1.28.2.5 2020/01/02 09:18:15 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran. 8 * by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -132,27 +132,27 @@ @@ -132,27 +132,27 @@
132 * these may be also called after attach, the thread lock is required. 132 * these may be also called after attach, the thread lock is required.
133 * 133 *
134 * In addition, there is an additional lock. 134 * In addition, there is an additional lock.
135 * 135 *
136 * - track->lock. This is an atomic variable and is similar to the 136 * - track->lock. This is an atomic variable and is similar to the
137 * "interrupt lock". This is one for each track. If any thread context 137 * "interrupt lock". This is one for each track. If any thread context
138 * (and software interrupt context) and hardware interrupt context who 138 * (and software interrupt context) and hardware interrupt context who
139 * want to access some variables on this track, they must acquire this 139 * want to access some variables on this track, they must acquire this
140 * lock before. It protects track's consistency between hardware 140 * lock before. It protects track's consistency between hardware
141 * interrupt context and others. 141 * interrupt context and others.
142 */ 142 */
143 143
144#include <sys/cdefs.h> 144#include <sys/cdefs.h>
145__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.28.2.4 2019/11/19 12:58:29 martin Exp $"); 145__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.28.2.5 2020/01/02 09:18:15 martin Exp $");
146 146
147#ifdef _KERNEL_OPT 147#ifdef _KERNEL_OPT
148#include "audio.h" 148#include "audio.h"
149#include "midi.h" 149#include "midi.h"
150#endif 150#endif
151 151
152#if NAUDIO > 0 152#if NAUDIO > 0
153 153
154#ifdef _KERNEL 154#ifdef _KERNEL
155 155
156#include <sys/types.h> 156#include <sys/types.h>
157#include <sys/param.h> 157#include <sys/param.h>
158#include <sys/atomic.h> 158#include <sys/atomic.h>
@@ -3051,61 +3051,51 @@ audioctl_open(dev_t dev, struct audio_so @@ -3051,61 +3051,51 @@ audioctl_open(dev_t dev, struct audio_so
3051 af = kmem_zalloc(sizeof(audio_file_t), KM_SLEEP); 3051 af = kmem_zalloc(sizeof(audio_file_t), KM_SLEEP);
3052 af->sc = sc; 3052 af->sc = sc;
3053 af->dev = dev; 3053 af->dev = dev;
3054 3054
3055 /* Not necessary to insert sc_files. */ 3055 /* Not necessary to insert sc_files. */
3056 3056
3057 error = fd_clone(fp, fd, flags, &audio_fileops, af); 3057 error = fd_clone(fp, fd, flags, &audio_fileops, af);
3058 KASSERT(error == EMOVEFD); 3058 KASSERT(error == EMOVEFD);
3059 3059
3060 return error; 3060 return error;
3061} 3061}
3062 3062
3063/* 3063/*
3064 * Reallocate 'memblock' with specified 'bytes' if 'bytes' > 0. 
3065 * Or free 'memblock' and return NULL if 'byte' is zero. 
3066 */ 
3067static void * 
3068audio_realloc(void *memblock, size_t bytes) 
3069{ 
3070 
3071 if (memblock != NULL) { 
3072 if (bytes != 0) { 
3073 return kern_realloc(memblock, bytes, M_NOWAIT); 
3074 } else { 
3075 kern_free(memblock); 
3076 return NULL; 
3077 } 
3078 } else { 
3079 if (bytes != 0) { 
3080 return kern_malloc(bytes, M_NOWAIT); 
3081 } else { 
3082 return NULL; 
3083 } 
3084 } 
3085} 
3086 
3087/* 
3088 * Free 'mem' if available, and initialize the pointer. 3064 * Free 'mem' if available, and initialize the pointer.
3089 * For this reason, this is implemented as macro. 3065 * For this reason, this is implemented as macro.
3090 */ 3066 */
3091#define audio_free(mem) do { \ 3067#define audio_free(mem) do { \
3092 if (mem != NULL) { \ 3068 if (mem != NULL) { \
3093 kern_free(mem); \ 3069 kern_free(mem); \
3094 mem = NULL; \ 3070 mem = NULL; \
3095 } \ 3071 } \
3096} while (0) 3072} while (0)
3097 3073
3098/* 3074/*
 3075 * (Re)allocate 'memblock' with specified 'bytes'.
 3076 * bytes must not be 0.
 3077 * This function never returns NULL.
 3078 */
 3079static void *
 3080audio_realloc(void *memblock, size_t bytes)
 3081{
 3082
 3083 KASSERT(bytes != 0);
 3084 audio_free(memblock);
 3085 return kern_malloc(bytes, M_WAITOK);
 3086}
 3087
 3088/*
3099 * (Re)allocate usrbuf with 'newbufsize' bytes. 3089 * (Re)allocate usrbuf with 'newbufsize' bytes.
3100 * Use this function for usrbuf because only usrbuf can be mmapped. 3090 * Use this function for usrbuf because only usrbuf can be mmapped.
3101 * If successful, it updates track->usrbuf.mem, track->usrbuf.capacity and 3091 * If successful, it updates track->usrbuf.mem, track->usrbuf.capacity and
3102 * returns 0. Otherwise, it clears track->usrbuf.mem, track->usrbuf.capacity 3092 * returns 0. Otherwise, it clears track->usrbuf.mem, track->usrbuf.capacity
3103 * and returns errno. 3093 * and returns errno.
3104 * It must be called before updating usrbuf.capacity. 3094 * It must be called before updating usrbuf.capacity.
3105 */ 3095 */
3106static int 3096static int
3107audio_realloc_usrbuf(audio_track_t *track, int newbufsize) 3097audio_realloc_usrbuf(audio_track_t *track, int newbufsize)
3108{ 3098{
3109 struct audio_softc *sc; 3099 struct audio_softc *sc;
3110 vaddr_t vstart; 3100 vaddr_t vstart;
3111 vsize_t oldvsize; 3101 vsize_t oldvsize;
@@ -3650,38 +3640,36 @@ abort: @@ -3650,38 +3640,36 @@ abort:
3650#endif 3640#endif
3651 return NULL; 3641 return NULL;
3652} 3642}
3653 3643
3654/* 3644/*
3655 * Initialize the codec stage of this track as necessary. 3645 * Initialize the codec stage of this track as necessary.
3656 * If successful, it initializes the codec stage as necessary, stores updated 3646 * If successful, it initializes the codec stage as necessary, stores updated
3657 * last_dst in *last_dstp in any case, and returns 0. 3647 * last_dst in *last_dstp in any case, and returns 0.
3658 * Otherwise, it returns errno without modifying *last_dstp. 3648 * Otherwise, it returns errno without modifying *last_dstp.
3659 */ 3649 */
3660static int 3650static int
3661audio_track_init_codec(audio_track_t *track, audio_ring_t **last_dstp) 3651audio_track_init_codec(audio_track_t *track, audio_ring_t **last_dstp)
3662{ 3652{
3663 struct audio_softc *sc; 
3664 audio_ring_t *last_dst; 3653 audio_ring_t *last_dst;
3665 audio_ring_t *srcbuf; 3654 audio_ring_t *srcbuf;
3666 audio_format2_t *srcfmt; 3655 audio_format2_t *srcfmt;
3667 audio_format2_t *dstfmt; 3656 audio_format2_t *dstfmt;
3668 audio_filter_arg_t *arg; 3657 audio_filter_arg_t *arg;
3669 u_int len; 3658 u_int len;
3670 int error; 3659 int error;
3671 3660
3672 KASSERT(track); 3661 KASSERT(track);
3673 3662
3674 sc = track->mixer->sc; 
3675 last_dst = *last_dstp; 3663 last_dst = *last_dstp;
3676 dstfmt = &last_dst->fmt; 3664 dstfmt = &last_dst->fmt;
3677 srcfmt = &track->inputfmt; 3665 srcfmt = &track->inputfmt;
3678 srcbuf = &track->codec.srcbuf; 3666 srcbuf = &track->codec.srcbuf;
3679 error = 0; 3667 error = 0;
3680 3668
3681 if (srcfmt->encoding != dstfmt->encoding 3669 if (srcfmt->encoding != dstfmt->encoding
3682 || srcfmt->precision != dstfmt->precision 3670 || srcfmt->precision != dstfmt->precision
3683 || srcfmt->stride != dstfmt->stride) { 3671 || srcfmt->stride != dstfmt->stride) {
3684 track->codec.dst = last_dst; 3672 track->codec.dst = last_dst;
3685 3673
3686 srcbuf->fmt = *dstfmt; 3674 srcbuf->fmt = *dstfmt;
3687 srcbuf->fmt.encoding = srcfmt->encoding; 3675 srcbuf->fmt.encoding = srcfmt->encoding;
@@ -3690,69 +3678,61 @@ audio_track_init_codec(audio_track_t *tr @@ -3690,69 +3678,61 @@ audio_track_init_codec(audio_track_t *tr
3690 3678
3691 track->codec.filter = audio_track_get_codec(track, 3679 track->codec.filter = audio_track_get_codec(track,
3692 &srcbuf->fmt, dstfmt); 3680 &srcbuf->fmt, dstfmt);
3693 if (track->codec.filter == NULL) { 3681 if (track->codec.filter == NULL) {
3694 error = EINVAL; 3682 error = EINVAL;
3695 goto abort; 3683 goto abort;
3696 } 3684 }
3697 3685
3698 srcbuf->head = 0; 3686 srcbuf->head = 0;
3699 srcbuf->used = 0; 3687 srcbuf->used = 0;
3700 srcbuf->capacity = frame_per_block(track->mixer, &srcbuf->fmt); 3688 srcbuf->capacity = frame_per_block(track->mixer, &srcbuf->fmt);
3701 len = auring_bytelen(srcbuf); 3689 len = auring_bytelen(srcbuf);
3702 srcbuf->mem = audio_realloc(srcbuf->mem, len); 3690 srcbuf->mem = audio_realloc(srcbuf->mem, len);
3703 if (srcbuf->mem == NULL) { 
3704 device_printf(sc->sc_dev, "%s: malloc(%d) failed\n", 
3705 __func__, len); 
3706 error = ENOMEM; 
3707 goto abort; 
3708 } 
3709 3691
3710 arg = &track->codec.arg; 3692 arg = &track->codec.arg;
3711 arg->srcfmt = &srcbuf->fmt; 3693 arg->srcfmt = &srcbuf->fmt;
3712 arg->dstfmt = dstfmt; 3694 arg->dstfmt = dstfmt;
3713 arg->context = NULL; 3695 arg->context = NULL;
3714 3696
3715 *last_dstp = srcbuf; 3697 *last_dstp = srcbuf;
3716 return 0; 3698 return 0;
3717 } 3699 }
3718 3700
3719abort: 3701abort:
3720 track->codec.filter = NULL; 3702 track->codec.filter = NULL;
3721 audio_free(srcbuf->mem); 3703 audio_free(srcbuf->mem);
3722 return error; 3704 return error;
3723} 3705}
3724 3706
3725/* 3707/*
3726 * Initialize the chvol stage of this track as necessary. 3708 * Initialize the chvol stage of this track as necessary.
3727 * If successful, it initializes the chvol stage as necessary, stores updated 3709 * If successful, it initializes the chvol stage as necessary, stores updated
3728 * last_dst in *last_dstp in any case, and returns 0. 3710 * last_dst in *last_dstp in any case, and returns 0.
3729 * Otherwise, it returns errno without modifying *last_dstp. 3711 * Otherwise, it returns errno without modifying *last_dstp.
3730 */ 3712 */
3731static int 3713static int
3732audio_track_init_chvol(audio_track_t *track, audio_ring_t **last_dstp) 3714audio_track_init_chvol(audio_track_t *track, audio_ring_t **last_dstp)
3733{ 3715{
3734 struct audio_softc *sc; 
3735 audio_ring_t *last_dst; 3716 audio_ring_t *last_dst;
3736 audio_ring_t *srcbuf; 3717 audio_ring_t *srcbuf;
3737 audio_format2_t *srcfmt; 3718 audio_format2_t *srcfmt;
3738 audio_format2_t *dstfmt; 3719 audio_format2_t *dstfmt;
3739 audio_filter_arg_t *arg; 3720 audio_filter_arg_t *arg;
3740 u_int len; 3721 u_int len;
3741 int error; 3722 int error;
3742 3723
3743 KASSERT(track); 3724 KASSERT(track);
3744 3725
3745 sc = track->mixer->sc; 
3746 last_dst = *last_dstp; 3726 last_dst = *last_dstp;
3747 dstfmt = &last_dst->fmt; 3727 dstfmt = &last_dst->fmt;
3748 srcfmt = &track->inputfmt; 3728 srcfmt = &track->inputfmt;
3749 srcbuf = &track->chvol.srcbuf; 3729 srcbuf = &track->chvol.srcbuf;
3750 error = 0; 3730 error = 0;
3751 3731
3752 /* Check whether channel volume conversion is necessary. */ 3732 /* Check whether channel volume conversion is necessary. */
3753 bool use_chvol = false; 3733 bool use_chvol = false;
3754 for (int ch = 0; ch < srcfmt->channels; ch++) { 3734 for (int ch = 0; ch < srcfmt->channels; ch++) {
3755 if (track->ch_volume[ch] != 256) { 3735 if (track->ch_volume[ch] != 256) {
3756 use_chvol = true; 3736 use_chvol = true;
3757 break; 3737 break;
3758 } 3738 }
@@ -3760,71 +3740,62 @@ audio_track_init_chvol(audio_track_t *tr @@ -3760,71 +3740,62 @@ audio_track_init_chvol(audio_track_t *tr
3760 3740
3761 if (use_chvol == true) { 3741 if (use_chvol == true) {
3762 track->chvol.dst = last_dst; 3742 track->chvol.dst = last_dst;
3763 track->chvol.filter = audio_track_chvol; 3743 track->chvol.filter = audio_track_chvol;
3764 3744
3765 srcbuf->fmt = *dstfmt; 3745 srcbuf->fmt = *dstfmt;
3766 /* no format conversion occurs */ 3746 /* no format conversion occurs */
3767 3747
3768 srcbuf->head = 0; 3748 srcbuf->head = 0;
3769 srcbuf->used = 0; 3749 srcbuf->used = 0;
3770 srcbuf->capacity = frame_per_block(track->mixer, &srcbuf->fmt); 3750 srcbuf->capacity = frame_per_block(track->mixer, &srcbuf->fmt);
3771 len = auring_bytelen(srcbuf); 3751 len = auring_bytelen(srcbuf);
3772 srcbuf->mem = audio_realloc(srcbuf->mem, len); 3752 srcbuf->mem = audio_realloc(srcbuf->mem, len);
3773 if (srcbuf->mem == NULL) { 
3774 device_printf(sc->sc_dev, "%s: malloc(%d) failed\n", 
3775 __func__, len); 
3776 error = ENOMEM; 
3777 goto abort; 
3778 } 
3779 3753
3780 arg = &track->chvol.arg; 3754 arg = &track->chvol.arg;
3781 arg->srcfmt = &srcbuf->fmt; 3755 arg->srcfmt = &srcbuf->fmt;
3782 arg->dstfmt = dstfmt; 3756 arg->dstfmt = dstfmt;
3783 arg->context = track->ch_volume; 3757 arg->context = track->ch_volume;
3784 3758
3785 *last_dstp = srcbuf; 3759 *last_dstp = srcbuf;
3786 return 0; 3760 return 0;
3787 } 3761 }
3788 3762
3789abort: 
3790 track->chvol.filter = NULL; 3763 track->chvol.filter = NULL;
3791 audio_free(srcbuf->mem); 3764 audio_free(srcbuf->mem);
3792 return error; 3765 return error;
3793} 3766}
3794 3767
3795/* 3768/*
3796 * Initialize the chmix stage of this track as necessary. 3769 * Initialize the chmix stage of this track as necessary.
3797 * If successful, it initializes the chmix stage as necessary, stores updated 3770 * If successful, it initializes the chmix stage as necessary, stores updated
3798 * last_dst in *last_dstp in any case, and returns 0. 3771 * last_dst in *last_dstp in any case, and returns 0.
3799 * Otherwise, it returns errno without modifying *last_dstp. 3772 * Otherwise, it returns errno without modifying *last_dstp.
3800 */ 3773 */
3801static int 3774static int
3802audio_track_init_chmix(audio_track_t *track, audio_ring_t **last_dstp) 3775audio_track_init_chmix(audio_track_t *track, audio_ring_t **last_dstp)
3803{ 3776{
3804 struct audio_softc *sc; 
3805 audio_ring_t *last_dst; 3777 audio_ring_t *last_dst;
3806 audio_ring_t *srcbuf; 3778 audio_ring_t *srcbuf;
3807 audio_format2_t *srcfmt; 3779 audio_format2_t *srcfmt;
3808 audio_format2_t *dstfmt; 3780 audio_format2_t *dstfmt;
3809 audio_filter_arg_t *arg; 3781 audio_filter_arg_t *arg;
3810 u_int srcch; 3782 u_int srcch;
3811 u_int dstch; 3783 u_int dstch;
3812 u_int len; 3784 u_int len;
3813 int error; 3785 int error;
3814 3786
3815 KASSERT(track); 3787 KASSERT(track);
3816 3788
3817 sc = track->mixer->sc; 
3818 last_dst = *last_dstp; 3789 last_dst = *last_dstp;
3819 dstfmt = &last_dst->fmt; 3790 dstfmt = &last_dst->fmt;
3820 srcfmt = &track->inputfmt; 3791 srcfmt = &track->inputfmt;
3821 srcbuf = &track->chmix.srcbuf; 3792 srcbuf = &track->chmix.srcbuf;
3822 error = 0; 3793 error = 0;
3823 3794
3824 srcch = srcfmt->channels; 3795 srcch = srcfmt->channels;
3825 dstch = dstfmt->channels; 3796 dstch = dstfmt->channels;
3826 if (srcch != dstch) { 3797 if (srcch != dstch) {
3827 track->chmix.dst = last_dst; 3798 track->chmix.dst = last_dst;
3828 3799
3829 if (srcch >= 2 && dstch == 1) { 3800 if (srcch >= 2 && dstch == 1) {
3830 track->chmix.filter = audio_track_chmix_mixLR; 3801 track->chmix.filter = audio_track_chmix_mixLR;
@@ -3835,73 +3806,64 @@ audio_track_init_chmix(audio_track_t *tr @@ -3835,73 +3806,64 @@ audio_track_init_chmix(audio_track_t *tr
3835 } else { 3806 } else {
3836 track->chmix.filter = audio_track_chmix_expand; 3807 track->chmix.filter = audio_track_chmix_expand;
3837 } 3808 }
3838 3809
3839 srcbuf->fmt = *dstfmt; 3810 srcbuf->fmt = *dstfmt;
3840 srcbuf->fmt.channels = srcch; 3811 srcbuf->fmt.channels = srcch;
3841 3812
3842 srcbuf->head = 0; 3813 srcbuf->head = 0;
3843 srcbuf->used = 0; 3814 srcbuf->used = 0;
3844 /* XXX The buffer size should be able to calculate. */ 3815 /* XXX The buffer size should be able to calculate. */
3845 srcbuf->capacity = frame_per_block(track->mixer, &srcbuf->fmt); 3816 srcbuf->capacity = frame_per_block(track->mixer, &srcbuf->fmt);
3846 len = auring_bytelen(srcbuf); 3817 len = auring_bytelen(srcbuf);
3847 srcbuf->mem = audio_realloc(srcbuf->mem, len); 3818 srcbuf->mem = audio_realloc(srcbuf->mem, len);
3848 if (srcbuf->mem == NULL) { 
3849 device_printf(sc->sc_dev, "%s: malloc(%d) failed\n", 
3850 __func__, len); 
3851 error = ENOMEM; 
3852 goto abort; 
3853 } 
3854 3819
3855 arg = &track->chmix.arg; 3820 arg = &track->chmix.arg;
3856 arg->srcfmt = &srcbuf->fmt; 3821 arg->srcfmt = &srcbuf->fmt;
3857 arg->dstfmt = dstfmt; 3822 arg->dstfmt = dstfmt;
3858 arg->context = NULL; 3823 arg->context = NULL;
3859 3824
3860 *last_dstp = srcbuf; 3825 *last_dstp = srcbuf;
3861 return 0; 3826 return 0;
3862 } 3827 }
3863 3828
3864abort: 
3865 track->chmix.filter = NULL; 3829 track->chmix.filter = NULL;
3866 audio_free(srcbuf->mem); 3830 audio_free(srcbuf->mem);
3867 return error; 3831 return error;
3868} 3832}
3869 3833
3870/* 3834/*
3871 * Initialize the freq stage of this track as necessary. 3835 * Initialize the freq stage of this track as necessary.
3872 * If successful, it initializes the freq stage as necessary, stores updated 3836 * If successful, it initializes the freq stage as necessary, stores updated
3873 * last_dst in *last_dstp in any case, and returns 0. 3837 * last_dst in *last_dstp in any case, and returns 0.
3874 * Otherwise, it returns errno without modifying *last_dstp. 3838 * Otherwise, it returns errno without modifying *last_dstp.
3875 */ 3839 */
3876static int 3840static int
3877audio_track_init_freq(audio_track_t *track, audio_ring_t **last_dstp) 3841audio_track_init_freq(audio_track_t *track, audio_ring_t **last_dstp)
3878{ 3842{
3879 struct audio_softc *sc; 
3880 audio_ring_t *last_dst; 3843 audio_ring_t *last_dst;
3881 audio_ring_t *srcbuf; 3844 audio_ring_t *srcbuf;
3882 audio_format2_t *srcfmt; 3845 audio_format2_t *srcfmt;
3883 audio_format2_t *dstfmt; 3846 audio_format2_t *dstfmt;
3884 audio_filter_arg_t *arg; 3847 audio_filter_arg_t *arg;
3885 uint32_t srcfreq; 3848 uint32_t srcfreq;
3886 uint32_t dstfreq; 3849 uint32_t dstfreq;
3887 u_int dst_capacity; 3850 u_int dst_capacity;
3888 u_int mod; 3851 u_int mod;
3889 u_int len; 3852 u_int len;
3890 int error; 3853 int error;
3891 3854
3892 KASSERT(track); 3855 KASSERT(track);
3893 3856
3894 sc = track->mixer->sc; 
3895 last_dst = *last_dstp; 3857 last_dst = *last_dstp;
3896 dstfmt = &last_dst->fmt; 3858 dstfmt = &last_dst->fmt;
3897 srcfmt = &track->inputfmt; 3859 srcfmt = &track->inputfmt;
3898 srcbuf = &track->freq.srcbuf; 3860 srcbuf = &track->freq.srcbuf;
3899 error = 0; 3861 error = 0;
3900 3862
3901 srcfreq = srcfmt->sample_rate; 3863 srcfreq = srcfmt->sample_rate;
3902 dstfreq = dstfmt->sample_rate; 3864 dstfreq = dstfmt->sample_rate;
3903 if (srcfreq != dstfreq) { 3865 if (srcfreq != dstfreq) {
3904 track->freq.dst = last_dst; 3866 track->freq.dst = last_dst;
3905 3867
3906 memset(track->freq_prev, 0, sizeof(track->freq_prev)); 3868 memset(track->freq_prev, 0, sizeof(track->freq_prev));
3907 memset(track->freq_curr, 0, sizeof(track->freq_curr)); 3869 memset(track->freq_curr, 0, sizeof(track->freq_curr));
@@ -3920,43 +3882,36 @@ audio_track_init_freq(audio_track_t *tra @@ -3920,43 +3882,36 @@ audio_track_init_freq(audio_track_t *tra
3920 } else { 3882 } else {
3921 track->freq.filter = audio_track_freq_down; 3883 track->freq.filter = audio_track_freq_down;
3922 track->freq_current = 0; 3884 track->freq_current = 0;
3923 } 3885 }
3924 3886
3925 srcbuf->fmt = *dstfmt; 3887 srcbuf->fmt = *dstfmt;
3926 srcbuf->fmt.sample_rate = srcfreq; 3888 srcbuf->fmt.sample_rate = srcfreq;
3927 3889
3928 srcbuf->head = 0; 3890 srcbuf->head = 0;
3929 srcbuf->used = 0; 3891 srcbuf->used = 0;
3930 srcbuf->capacity = frame_per_block(track->mixer, &srcbuf->fmt); 3892 srcbuf->capacity = frame_per_block(track->mixer, &srcbuf->fmt);
3931 len = auring_bytelen(srcbuf); 3893 len = auring_bytelen(srcbuf);
3932 srcbuf->mem = audio_realloc(srcbuf->mem, len); 3894 srcbuf->mem = audio_realloc(srcbuf->mem, len);
3933 if (srcbuf->mem == NULL) { 
3934 device_printf(sc->sc_dev, "%s: malloc(%d) failed\n", 
3935 __func__, len); 
3936 error = ENOMEM; 
3937 goto abort; 
3938 } 
3939 3895
3940 arg = &track->freq.arg; 3896 arg = &track->freq.arg;
3941 arg->srcfmt = &srcbuf->fmt; 3897 arg->srcfmt = &srcbuf->fmt;
3942 arg->dstfmt = dstfmt;/*&last_dst->fmt;*/ 3898 arg->dstfmt = dstfmt;/*&last_dst->fmt;*/
3943 arg->context = track; 3899 arg->context = track;
3944 3900
3945 *last_dstp = srcbuf; 3901 *last_dstp = srcbuf;
3946 return 0; 3902 return 0;
3947 } 3903 }
3948 3904
3949abort: 
3950 track->freq.filter = NULL; 3905 track->freq.filter = NULL;
3951 audio_free(srcbuf->mem); 3906 audio_free(srcbuf->mem);
3952 return error; 3907 return error;
3953} 3908}
3954 3909
3955/* 3910/*
3956 * When playing back: (e.g. if codec and freq stage are valid) 3911 * When playing back: (e.g. if codec and freq stage are valid)
3957 * 3912 *
3958 * write 3913 * write
3959 * | uiomove 3914 * | uiomove
3960 * v 3915 * v
3961 * usrbuf [...............] byte ring buffer (mmap-able) 3916 * usrbuf [...............] byte ring buffer (mmap-able)
3962 * | memcpy 3917 * | memcpy
@@ -4118,32 +4073,26 @@ audio_track_set_format(audio_track_t *tr @@ -4118,32 +4073,26 @@ audio_track_set_format(audio_track_t *tr
4118 4073
4119 /* Stage input buffer */ 4074 /* Stage input buffer */
4120 track->input = last_dst; 4075 track->input = last_dst;
4121 4076
4122 /* 4077 /*
4123 * On the recording track, make the first stage a ring buffer. 4078 * On the recording track, make the first stage a ring buffer.
4124 * XXX is there a better way? 4079 * XXX is there a better way?
4125 */ 4080 */
4126 if (audio_track_is_record(track)) { 4081 if (audio_track_is_record(track)) {
4127 track->input->capacity = NBLKOUT * 4082 track->input->capacity = NBLKOUT *
4128 frame_per_block(track->mixer, &track->input->fmt); 4083 frame_per_block(track->mixer, &track->input->fmt);
4129 len = auring_bytelen(track->input); 4084 len = auring_bytelen(track->input);
4130 track->input->mem = audio_realloc(track->input->mem, len); 4085 track->input->mem = audio_realloc(track->input->mem, len);
4131 if (track->input->mem == NULL) { 
4132 device_printf(sc->sc_dev, "malloc input(%d) failed\n", 
4133 len); 
4134 error = ENOMEM; 
4135 goto error; 
4136 } 
4137 } 4086 }
4138 4087
4139 /* 4088 /*
4140 * Output buffer. 4089 * Output buffer.
4141 * On the playback track, its capacity is NBLKOUT blocks. 4090 * On the playback track, its capacity is NBLKOUT blocks.
4142 * On the recording track, its capacity is 1 block. 4091 * On the recording track, its capacity is 1 block.
4143 */ 4092 */
4144 track->outbuf.head = 0; 4093 track->outbuf.head = 0;
4145 track->outbuf.used = 0; 4094 track->outbuf.used = 0;
4146 track->outbuf.capacity = frame_per_block(track->mixer, 4095 track->outbuf.capacity = frame_per_block(track->mixer,
4147 &track->outbuf.fmt); 4096 &track->outbuf.fmt);
4148 if (audio_track_is_playback(track)) 4097 if (audio_track_is_playback(track))
4149 track->outbuf.capacity *= NBLKOUT; 4098 track->outbuf.capacity *= NBLKOUT;
@@ -4718,33 +4667,26 @@ audio_mixer_init(struct audio_softc *sc, @@ -4718,33 +4667,26 @@ audio_mixer_init(struct audio_softc *sc,
4718 mixer->swap_endian = true; 4667 mixer->swap_endian = true;
4719 TRACE(1, "swap_endian"); 4668 TRACE(1, "swap_endian");
4720 } 4669 }
4721 4670
4722 if (mode == AUMODE_PLAY) { 4671 if (mode == AUMODE_PLAY) {
4723 /* Mixing buffer */ 4672 /* Mixing buffer */
4724 mixer->mixfmt = mixer->track_fmt; 4673 mixer->mixfmt = mixer->track_fmt;
4725 mixer->mixfmt.precision *= 2; 4674 mixer->mixfmt.precision *= 2;
4726 mixer->mixfmt.stride *= 2; 4675 mixer->mixfmt.stride *= 2;
4727 /* XXX TODO: use some macros? */ 4676 /* XXX TODO: use some macros? */
4728 len = mixer->frames_per_block * mixer->mixfmt.channels * 4677 len = mixer->frames_per_block * mixer->mixfmt.channels *
4729 mixer->mixfmt.stride / NBBY; 4678 mixer->mixfmt.stride / NBBY;
4730 mixer->mixsample = audio_realloc(mixer->mixsample, len); 4679 mixer->mixsample = audio_realloc(mixer->mixsample, len);
4731 if (mixer->mixsample == NULL) { 
4732 device_printf(sc->sc_dev, 
4733 "%s: malloc mixsample(%d) failed\n", 
4734 __func__, len); 
4735 error = ENOMEM; 
4736 goto abort; 
4737 } 
4738 } else { 4680 } else {
4739 /* No mixing buffer for recording */ 4681 /* No mixing buffer for recording */
4740 } 4682 }
4741 4683
4742 if (reg->codec) { 4684 if (reg->codec) {
4743 mixer->codec = reg->codec; 4685 mixer->codec = reg->codec;
4744 mixer->codecarg.context = reg->context; 4686 mixer->codecarg.context = reg->context;
4745 if (mode == AUMODE_PLAY) { 4687 if (mode == AUMODE_PLAY) {
4746 mixer->codecarg.srcfmt = &mixer->track_fmt; 4688 mixer->codecarg.srcfmt = &mixer->track_fmt;
4747 mixer->codecarg.dstfmt = &mixer->hwbuf.fmt; 4689 mixer->codecarg.dstfmt = &mixer->hwbuf.fmt;
4748 } else { 4690 } else {
4749 mixer->codecarg.srcfmt = &mixer->hwbuf.fmt; 4691 mixer->codecarg.srcfmt = &mixer->hwbuf.fmt;
4750 mixer->codecarg.dstfmt = &mixer->track_fmt; 4692 mixer->codecarg.dstfmt = &mixer->track_fmt;