/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (C) 4Front Technologies 1996-2008.
*
*/
/*
* Purpose: Virtual mixing audio input routines
*
* This file contains the actual mixing and resampling engine for input.
*/
#include <sys/sysmacros.h>
#include "audio_impl.h"
void \
{ \
int ch = 0; \
\
do { /* for each channel */ \
int i; \
\
/* get value and adjust next channel offset */ \
\
i = nfr; \
\
do { /* for each frame */ \
\
scaled /= AUDIO_VOL_SCALE; \
\
\
tidx = 0; \
} \
} while (--i); \
ch++; \
}
/*
* Produce capture data. This takes data from the conversion buffer
* and copies it into the stream data buffer.
*/
static void
{
/*
* Copy data. We deal properly with wraps. Done as a
* do...while to minimize the number of tests.
*/
do {
unsigned nf;
unsigned nb;
}
} while (count);
}
void
{
audio_engine_t *e = arg;
audio_client_t *c;
uint64_t h;
mutex_enter(&e->e_lock);
mutex_exit(&e->e_lock);
return;
}
if (e->e_need_start) {
int rv;
mutex_exit(&e->e_lock);
audio_dev_warn(e->e_dev,
"failed starting input, rv = %d", rv);
return;
}
e->e_need_start = B_FALSE;
}
h = ENG_COUNT(e);
if (h < e->e_head) {
/*
* This is a sign of a serious bug. We should
* probably offline the device via FMA, if we ever
* support FMA for audio devices.
*/
ENG_STOP(e);
mutex_exit(&e->e_lock);
audio_dev_warn(e->e_dev,
"device malfunction: broken capture sample counter");
return;
}
e->e_head = h;
/* no room for data, not much we can do */
e->e_errors++;
e->e_overruns++;
}
/* consume all fragments in the buffer */
/*
* Consider doing the SYNC outside of the lock.
*/
int space;
int count;
/* skip over streams paused or not running */
continue;
}
/*
* Optionally convert fragment to requested sample
* format and rate.
*/
} else {
}
e->e_stream_overruns++;
e->e_errors++;
}
/* wake blocked threads (blocking reads, etc.) */
/*
* Add client to notification list. We'll
* process it after dropping the lock.
*/
(c->c_next_input == NULL)) {
auclnt_hold(c);
c->c_next_input = clist;
clist = c;
}
}
/*
* Update the tail pointer, and the data pointer.
*/
}
}
mutex_exit(&e->e_lock);
/*
* Notify client personalities.
*/
clist = c->c_next_input;
c->c_next_input = NULL;
c->c_input(c);
auclnt_release(c);
}
}