2005-01-06 01:43:34 +00:00
|
|
|
/*-
|
2003-09-07 16:28:03 +00:00
|
|
|
* Copyright (c) 1999 Cameron Grant <cg@freebsd.org>
|
update code dealing with snd_dbuf objects to do so using a functional interface
modify chn_setblocksize() to pick a default soft-blocksize appropriate to the
sample rate and format in use. it will aim for a power of two size small
enough to generate block sizes of at most 20ms. it will also set the
hard-blocksize taking into account rate/format conversions in use.
update drivers to implement setblocksize correctly:
updated, tested: sb16, emu10k1, maestro, solo
updated, untested: ad1816, ess, mss, sb8, csa
not updated: ds1, es137x, fm801, neomagic, t4dwave, via82c686
i lack hardware to test: ad1816, csa, fm801, neomagic
others will be updated/tested in the next few days.
2000-12-23 03:16:13 +00:00
|
|
|
* 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$
|
|
|
|
*/
|
|
|
|
|
2003-02-07 14:05:34 +00:00
|
|
|
#define SND_DMA(b) (sndbuf_getflags((b)) & SNDBUF_F_DMA)
|
2001-03-24 23:10:29 +00:00
|
|
|
#define SNDBUF_LOCKASSERT(b)
|
|
|
|
|
2003-02-07 14:05:34 +00:00
|
|
|
#define SNDBUF_F_DMA 0x00000001
|
2001-03-24 23:10:29 +00:00
|
|
|
#define SNDBUF_F_XRUN 0x00000002
|
|
|
|
#define SNDBUF_F_RUNNING 0x00000004
|
2007-02-01 09:46:03 +00:00
|
|
|
#define SNDBUF_F_MANAGED 0x00000008
|
2001-03-24 23:10:29 +00:00
|
|
|
|
2003-02-07 14:05:34 +00:00
|
|
|
#define SNDBUF_NAMELEN 48
|
|
|
|
|
|
|
|
struct snd_dbuf {
|
|
|
|
device_t dev;
|
|
|
|
u_int8_t *buf, *tmpbuf;
|
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
|
|
|
u_int8_t *shadbuf; /**< shadow buffer used w/ S_D_SILENCE/SKIP */
|
|
|
|
volatile int sl; /**< shadbuf ready length in # of bytes */
|
2007-06-14 11:15:51 +00:00
|
|
|
unsigned int bufsize, maxsize, allocsize;
|
2003-02-07 14:05:34 +00:00
|
|
|
volatile int dl; /* transfer size */
|
|
|
|
volatile int rp; /* pointers to the ready area */
|
|
|
|
volatile int rl; /* length of ready area */
|
|
|
|
volatile int hp;
|
|
|
|
volatile u_int32_t total, prev_total;
|
|
|
|
int dmachan, dir; /* dma channel */
|
|
|
|
u_int32_t fmt, spd, bps;
|
|
|
|
unsigned int blksz, blkcnt;
|
|
|
|
int xrun;
|
|
|
|
u_int32_t flags;
|
|
|
|
bus_dmamap_t dmamap;
|
|
|
|
bus_dma_tag_t dmatag;
|
2007-05-07 02:46:48 +00:00
|
|
|
bus_addr_t buf_addr;
|
2007-04-18 18:26:41 +00:00
|
|
|
int dmaflags;
|
2003-02-07 14:05:34 +00:00
|
|
|
struct selinfo sel;
|
2004-01-28 08:02:15 +00:00
|
|
|
struct pcm_channel *channel;
|
2003-02-07 14:05:34 +00:00
|
|
|
char name[SNDBUF_NAMELEN];
|
|
|
|
};
|
|
|
|
|
2004-01-28 08:02:15 +00:00
|
|
|
struct snd_dbuf *sndbuf_create(device_t dev, char *drv, char *desc, struct pcm_channel *channel);
|
2001-03-24 23:10:29 +00:00
|
|
|
void sndbuf_destroy(struct snd_dbuf *b);
|
|
|
|
|
|
|
|
void sndbuf_dump(struct snd_dbuf *b, char *s, u_int32_t what);
|
|
|
|
|
2007-04-18 18:26:41 +00:00
|
|
|
int sndbuf_alloc(struct snd_dbuf *b, bus_dma_tag_t dmatag, int dmaflags, unsigned int size);
|
2001-03-24 23:10:29 +00:00
|
|
|
int sndbuf_setup(struct snd_dbuf *b, void *buf, unsigned int size);
|
|
|
|
void sndbuf_free(struct snd_dbuf *b);
|
|
|
|
int sndbuf_resize(struct snd_dbuf *b, unsigned int blkcnt, unsigned int blksz);
|
|
|
|
int sndbuf_remalloc(struct snd_dbuf *b, unsigned int blkcnt, unsigned int blksz);
|
|
|
|
void sndbuf_reset(struct snd_dbuf *b);
|
|
|
|
void sndbuf_clear(struct snd_dbuf *b, unsigned int length);
|
2001-05-27 14:39:34 +00:00
|
|
|
void sndbuf_fillsilence(struct snd_dbuf *b);
|
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
|
|
|
void sndbuf_softreset(struct snd_dbuf *b);
|
|
|
|
void sndbuf_clearshadow(struct snd_dbuf *b);
|
2001-03-24 23:10:29 +00:00
|
|
|
|
|
|
|
u_int32_t sndbuf_getfmt(struct snd_dbuf *b);
|
|
|
|
int sndbuf_setfmt(struct snd_dbuf *b, u_int32_t fmt);
|
|
|
|
unsigned int sndbuf_getspd(struct snd_dbuf *b);
|
|
|
|
void sndbuf_setspd(struct snd_dbuf *b, unsigned int spd);
|
|
|
|
unsigned int sndbuf_getbps(struct snd_dbuf *b);
|
|
|
|
|
2003-02-20 17:31:12 +00:00
|
|
|
bus_addr_t sndbuf_getbufaddr(struct snd_dbuf *buf);
|
|
|
|
|
2001-03-24 23:10:29 +00:00
|
|
|
void *sndbuf_getbuf(struct snd_dbuf *b);
|
|
|
|
void *sndbuf_getbufofs(struct snd_dbuf *b, unsigned int ofs);
|
|
|
|
unsigned int sndbuf_getsize(struct snd_dbuf *b);
|
|
|
|
unsigned int sndbuf_getmaxsize(struct snd_dbuf *b);
|
2007-06-14 11:15:51 +00:00
|
|
|
unsigned int sndbuf_getallocsize(struct snd_dbuf *b);
|
2001-03-24 23:10:29 +00:00
|
|
|
unsigned int sndbuf_getalign(struct snd_dbuf *b);
|
|
|
|
unsigned int sndbuf_getblkcnt(struct snd_dbuf *b);
|
|
|
|
void sndbuf_setblkcnt(struct snd_dbuf *b, unsigned int blkcnt);
|
|
|
|
unsigned int sndbuf_getblksz(struct snd_dbuf *b);
|
|
|
|
void sndbuf_setblksz(struct snd_dbuf *b, unsigned int blksz);
|
|
|
|
unsigned int sndbuf_runsz(struct snd_dbuf *b);
|
|
|
|
void sndbuf_setrun(struct snd_dbuf *b, int go);
|
|
|
|
struct selinfo *sndbuf_getsel(struct snd_dbuf *b);
|
|
|
|
|
|
|
|
unsigned int sndbuf_getxrun(struct snd_dbuf *b);
|
2006-07-17 17:43:06 +00:00
|
|
|
void sndbuf_setxrun(struct snd_dbuf *b, unsigned int xrun);
|
2001-03-24 23:10:29 +00:00
|
|
|
unsigned int sndbuf_gethwptr(struct snd_dbuf *b);
|
|
|
|
void sndbuf_sethwptr(struct snd_dbuf *b, unsigned int ptr);
|
|
|
|
unsigned int sndbuf_getfree(struct snd_dbuf *b);
|
|
|
|
unsigned int sndbuf_getfreeptr(struct snd_dbuf *b);
|
|
|
|
unsigned int sndbuf_getready(struct snd_dbuf *b);
|
|
|
|
unsigned int sndbuf_getreadyptr(struct snd_dbuf *b);
|
|
|
|
unsigned int sndbuf_getblocks(struct snd_dbuf *b);
|
|
|
|
unsigned int sndbuf_getprevblocks(struct snd_dbuf *b);
|
|
|
|
unsigned int sndbuf_gettotal(struct snd_dbuf *b);
|
Welcome to Once-a-year Sound Mega-Commit. Enjoy numerous updates and fixes
in every sense.
General
-------
- Multichannel safe, endian safe, format safe
* Large part of critical pcm filters such as vchan.c, feeder_rate.c,
feeder_volume.c, feeder_fmt.c and feeder.c has been rewritten so that
using them does not cause the pcm data to be converted to 16bit little
endian.
* Macrosses for accessing pcm data safely are defined within sound.h in
the form of PCM_READ_* / PCM_WRITE_*
* Currently, most of them are probably limited for mono/stereo handling,
but the future addition of true multichannel will be much easier.
- Low latency operation
* Well, this require lot more works to do not just within sound driver,
but we're heading towards right direction. Buffer/block sizing within
channel.c is rewritten to calculate precise allocation for various
combination of sample/data/rate size. As a result, applying correct
SNDCTL_DSP_POLICY value will achive expected latency behaviour simmilar
to what commercial 4front driver do.
* Signal handling fix. ctrl+c of "cat /dev/zero > /dev/dsp" does not
result long delay.
* Eliminate sound truncation if the sound data is too small.
DIY:
1) Download / extract
http://people.freebsd.org/~ariff/lowlatency/shortfiles.tar.gz
2) Do a comparison between "cat state*.au > /dev/dsp" and
"for x in state*.au ; do cat $x > /dev/dsp ; done"
- there should be no "perceivable" differences.
Double close for PR kern/31445.
CAVEAT: Low latency come with (unbearable) price especially for poorly
written applications. Applications that trying to act smarter
by requesting (wrong) blocksize/blockcount will suffer the most.
Fixup samples/patches can be found at:
http://people.freebsd.org/~ariff/ports/
- Switch minimum/maximum sampling rate limit to "1" and "2016000" (48k * 42)
due to closer compatibility with 4front driver.
Discussed with: marcus@ (long time ago?)
- All driver specific sysctls in the form of "hw.snd.pcm%d.*" have been
moved to their own dev sysctl nodes, notably:
hw.snd.pcm%d.vchans -> dev.pcm.%d.vchans
Bump __FreeBSD_version.
Driver specific
---------------
- Ditto for sysctls.
- snd_atiixp, snd_es137x, snd_via8233, snd_hda
* Numerous cleanups and fixes.
* _EXPERIMENTAL_ polling mode support using simple callout_* mechanisme.
This was intended for pure debugging and latency measurement, but proven
good enough in few unexpected and rare cases (such as problematic shared
IRQ with GIANT devices - USB). Polling can be enabled/disabled through
dev.pcm.0.polling. Disabled by default.
- snd_ich
* Fix possible overflow during speed calibration. Delay final
initialization (pcm_setstatus) after calibration finished.
PR: kern/100169
Tested by: Kevin Overman <oberman@es.net>
* Inverted EAPD for few Nec VersaPro.
PR: kern/104715
Submitted by: KAWATA Masahiko <kawata@mta.biglobe.ne.jp>
Thanks to various people, notably Joel Dahl, Yuriy Tsibizov, Kevin Oberman,
those at #freebsd-azalia @ freenode and others for testing.
Joel Dahl will do the manpage update.
2006-11-26 12:24:06 +00:00
|
|
|
unsigned int snd_xbytes(unsigned int v, unsigned int from, unsigned int to);
|
|
|
|
unsigned int sndbuf_xbytes(unsigned int v, struct snd_dbuf *from, struct snd_dbuf *to);
|
|
|
|
u_int8_t sndbuf_zerodata(u_int32_t fmt);
|
2001-03-24 23:10:29 +00:00
|
|
|
void sndbuf_updateprevtotal(struct snd_dbuf *b);
|
|
|
|
|
|
|
|
int sndbuf_acquire(struct snd_dbuf *b, u_int8_t *from, unsigned int count);
|
|
|
|
int sndbuf_dispose(struct snd_dbuf *b, u_int8_t *to, unsigned int count);
|
|
|
|
int sndbuf_feed(struct snd_dbuf *from, struct snd_dbuf *to, struct pcm_channel *channel, struct pcm_feeder *feeder, unsigned int count);
|
|
|
|
|
|
|
|
u_int32_t sndbuf_getflags(struct snd_dbuf *b);
|
|
|
|
void sndbuf_setflags(struct snd_dbuf *b, u_int32_t flags, int on);
|
|
|
|
|
2003-02-07 14:05:34 +00:00
|
|
|
int sndbuf_dmasetup(struct snd_dbuf *b, struct resource *drq);
|
|
|
|
int sndbuf_dmasetdir(struct snd_dbuf *b, int dir);
|
|
|
|
void sndbuf_dma(struct snd_dbuf *b, int go);
|
|
|
|
int sndbuf_dmaptr(struct snd_dbuf *b);
|
|
|
|
void sndbuf_dmabounce(struct snd_dbuf *b);
|
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
|
|
|
|
|
|
|
#ifdef OSSV4_EXPERIMENT
|
|
|
|
void sndbuf_getpeaks(struct snd_dbuf *b, int *lp, int *rp);
|
|
|
|
#endif
|