freebsd-nq/sys/dev/sound/pcm/channel_if.m
Alexander Leidinger b611c801f0 MFp4 the sound Google Summer of Code project:
The goal was to sync with the OSSv4 API 4Front Technologies uses in their
proprietary OSS driver. This was successful as far as possible. The part
of the API which is stable is implemented, for the rest there are some
stubs already.

New system ioctls:
 - SNDCTL_SYSINFO - obtain audio system info (version, # of audio/midi/
   mixer devices, etc.)
 - SNDCTL_AUDIOINFO - fetch details about a specific audio device
 - SNDCTL_MIXERINFO - fetch details about a specific mixer device

New audio ioctls:
 - Sync groups (SNDCTL_DSP_SYNCGROUP/SNDCTL_DSP_SYNCSTART) which allow
   triggered playback/recording on multiple devices (even across processes
   simultaneously).
 - Peak meters (SNDCTL_DSP_GETIPEAKS/SNDCTL_DSP_GETOPEAKS) - can query
   audio drivers for peak levels (needs driver support, disabled for now).
 - Per channel playback/recording levels -
   SNDCTL_DSP_{GET,SET}{PLAY,REC}VOL.  Note that these are still in name
   only, just wrapping around the AC97-style mixer at the moment. The next
   step is to push them down to the drivers.

Audio ioctls still under development by 4Front (for which stubs may exist
in this commit):
 - SNDCTL_GETNAME, SNDCTL_{GET,SET}{SONG,LABEL}
 - SNDCTL_DSP_{GET,SET}_CHNORDER
 - SNDCTL_MIX_ENUMINFO, SNDCTL_MIX_EXTINFO - (might be documented enough in
   the OSS releases to work on this.  These ioctls cover the cool "twiddle
   any knob on your card" features.)

Missing:
 - SNDCTL_DSP_COOKEDMODE -- this ioctl is used to give applications direct
   access to a card's buffers, bypassing the feeder architecture.  It's
   a toughy -- "someone" needs to decide :
   (a) if this is desireable, and (b) if it's reasonably feasible.

Updates for driver writers:
 So far, only two routines to the channel class (in channel_if.m) are added.
 One is for fetching a list of discrete supported playback/recording rates
 of a channel, and the other is for fetching peak level info (useful for
 drawing peak meters).  Interested parties may want to help pushing down
 SNDCTL_DSP_{GET,SET}{PLAY,REC}VOL into the drivers.

To use the new stuff you need to rebuild the sound drivers or your kernel
(depending on if you use modules or not) and to install soundcard.h (a
buildworld/installworld handles this).

Sponsored by:	Google SoC 2006
Submitted by:	ryanb
Many thanks to:	4Front Technologies for their cooperation, explanations
		and the nice license of their soundcard.h.
2006-09-23 20:45:47 +00:00

207 lines
4.7 KiB
Objective-C

#-
# KOBJ
#
# Copyright (c) 2000 Cameron Grant <cg@freebsd.org>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# $FreeBSD$
#
#include <dev/sound/pcm/sound.h>
INTERFACE channel;
CODE {
static int
channel_nosetdir(kobj_t obj, void *data, int dir)
{
return 0;
}
static int
channel_noreset(kobj_t obj, void *data)
{
return 0;
}
static int
channel_noresetdone(kobj_t obj, void *data)
{
return 0;
}
static int
channel_nofree(kobj_t obj, void *data)
{
return 1;
}
static u_int32_t
channel_nogetptr(kobj_t obj, void *data)
{
return 0;
}
static int
channel_nonotify(kobj_t obj, void *data, u_int32_t changed)
{
return 0;
}
static int
channel_nogetpeaks(kobj_t obj, void *data, int *lpeak, int *rpeak)
{
return -1;
}
static int
channel_nogetrates(kobj_t obj, void *data, int **rates)
{
*rates = NULL;
return 0;
}
};
METHOD void* init {
kobj_t obj;
void *devinfo;
struct snd_dbuf *b;
struct pcm_channel *c;
int dir;
};
METHOD int free {
kobj_t obj;
void *data;
} DEFAULT channel_nofree;
METHOD int reset {
kobj_t obj;
void *data;
} DEFAULT channel_noreset;
METHOD int resetdone {
kobj_t obj;
void *data;
} DEFAULT channel_noresetdone;
METHOD int setdir {
kobj_t obj;
void *data;
int dir;
} DEFAULT channel_nosetdir;
METHOD u_int32_t setformat {
kobj_t obj;
void *data;
u_int32_t format;
};
METHOD u_int32_t setspeed {
kobj_t obj;
void *data;
u_int32_t speed;
};
METHOD u_int32_t setblocksize {
kobj_t obj;
void *data;
u_int32_t blocksize;
};
METHOD int trigger {
kobj_t obj;
void *data;
int go;
};
METHOD u_int32_t getptr {
kobj_t obj;
void *data;
} DEFAULT channel_nogetptr;
METHOD struct pcmchan_caps* getcaps {
kobj_t obj;
void *data;
};
METHOD int notify {
kobj_t obj;
void *data;
u_int32_t changed;
} DEFAULT channel_nonotify;
/**
* @brief Retrieve channel peak values
*
* This function is intended to obtain peak volume values for samples
* played/recorded on a channel. Values are on a linear scale from 0 to
* 32767. If the channel is monaural, a single value should be recorded
* in @c lpeak.
*
* If hardware support isn't available, the SNDCTL_DSP_GET[IO]PEAKS
* operation should return EINVAL. However, we may opt to provide
* software support that the user may toggle via sysctl/mixext.
*
* @param obj standard kobj object (usually @c channel->methods)
* @param data driver-specific data (usually @c channel->devinfo)
* @param lpeak pointer to store left peak level
* @param rpeak pointer to store right peak level
*
* @retval -1 Error; usually operation isn't supported.
* @retval 0 success
*/
METHOD int getpeaks {
kobj_t obj;
void *data;
int *lpeak;
int *rpeak;
} DEFAULT channel_nogetpeaks;
/**
* @brief Retrieve discrete supported sample rates
*
* Some cards operate at fixed rates, and this call is intended to retrieve
* those rates primarily for when in-kernel rate adjustment is undesirable
* (e.g., application wants direct DMA access after setting a channel to run
* "uncooked").
*
* The parameter @c rates is a double pointer which will be reset to
* point to an array of supported sample rates. The number of elements
* in the array is returned to the caller.
*
* @param obj standard kobj object (usually @c channel->methods)
* @param data driver-specific data (usually @c channel->devinfo)
* @param rates rate array pointer
*
* @return Number of rates in the array
*/
METHOD int getrates {
kobj_t obj;
void *data;
int **rates;
} DEFAULT channel_nogetrates;