2005-01-06 01:43:34 +00:00
|
|
|
/*-
|
2004-01-09 06:38:11 +00:00
|
|
|
* Copyright (c) 2004 David O'Brien <obrien@FreeBSD.org>
|
2004-01-11 10:30:56 +00:00
|
|
|
* Copyright (c) 2003 Orlando Bassotto <orlando.bassotto@ieo-research.it>
|
2003-09-07 16:28:03 +00:00
|
|
|
* Copyright (c) 1999 Cameron Grant <cg@freebsd.org>
|
2000-04-02 07:41:17 +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, WHETHERIN CONTRACT, STRICT
|
|
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
2001-05-30 22:46:40 +00:00
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
2000-04-02 07:41:17 +00:00
|
|
|
* SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
#ifdef HAVE_KERNEL_OPTION_HEADERS
|
|
|
|
#include "opt_snd.h"
|
|
|
|
#endif
|
|
|
|
|
2000-04-02 07:41:17 +00:00
|
|
|
#include <dev/sound/pcm/sound.h>
|
|
|
|
#include <dev/sound/pcm/ac97.h>
|
2012-01-03 21:04:54 +00:00
|
|
|
#include <dev/sound/pci/emuxkireg.h>
|
2000-04-02 07:41:17 +00:00
|
|
|
|
2003-08-22 07:08:17 +00:00
|
|
|
#include <dev/pci/pcireg.h>
|
|
|
|
#include <dev/pci/pcivar.h>
|
2000-04-02 07:41:17 +00:00
|
|
|
#include <sys/queue.h>
|
|
|
|
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
#include <dev/sound/midi/mpu401.h>
|
|
|
|
#include "mpufoi_if.h"
|
|
|
|
|
2001-08-23 11:30:52 +00:00
|
|
|
SND_DECLARE_FILE("$FreeBSD$");
|
|
|
|
|
2000-04-02 07:41:17 +00:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
2004-01-09 06:38:11 +00:00
|
|
|
#define NUM_G 64 /* use all channels */
|
|
|
|
#define WAVEOUT_MAXBUFSIZE 32768
|
|
|
|
#define EMUPAGESIZE 4096 /* don't change */
|
2004-01-11 10:30:56 +00:00
|
|
|
#define EMUMAXPAGES (WAVEOUT_MAXBUFSIZE * NUM_G / EMUPAGESIZE)
|
|
|
|
#define EMU10K1_PCI_ID 0x00021102 /* 1102 => Creative Labs Vendor ID */
|
|
|
|
#define EMU10K2_PCI_ID 0x00041102
|
2005-03-01 08:58:06 +00:00
|
|
|
#define EMU10K3_PCI_ID 0x00081102
|
2003-04-20 07:43:09 +00:00
|
|
|
#define EMU_DEFAULT_BUFSZ 4096
|
2004-01-11 10:30:56 +00:00
|
|
|
#define EMU_MAX_CHANS 8
|
2003-04-20 07:43:09 +00:00
|
|
|
#define EMU_CHANS 4
|
2004-01-11 10:30:56 +00:00
|
|
|
|
|
|
|
#define MAXREQVOICES 8
|
|
|
|
#define RESERVED 0
|
|
|
|
#define NUM_MIDI 16
|
|
|
|
#define NUM_FXSENDS 4
|
|
|
|
|
|
|
|
#define TMEMSIZE 256*1024
|
|
|
|
#define TMEMSIZEREG 4
|
|
|
|
|
|
|
|
#define ENABLE 0xffffffff
|
|
|
|
#define DISABLE 0x00000000
|
2012-01-03 21:04:54 +00:00
|
|
|
#define ENV_ON EMU_CHAN_DCYSUSV_CHANNELENABLE_MASK
|
2004-01-09 06:38:11 +00:00
|
|
|
#define ENV_OFF 0x00 /* XXX: should this be 1? */
|
2000-04-02 07:41:17 +00:00
|
|
|
|
2012-01-03 21:04:54 +00:00
|
|
|
#define EMU_A_IOCFG_GPOUT_A 0x40
|
|
|
|
#define EMU_A_IOCFG_GPOUT_D 0x04
|
|
|
|
#define EMU_A_IOCFG_GPOUT_AD (EMU_A_IOCFG_GPOUT_A|EMU_A_IOCFG_GPOUT_D) /* EMU_A_IOCFG_GPOUT0 */
|
|
|
|
|
|
|
|
#define EMU_HCFG_GPOUT1 0x00000800
|
|
|
|
|
|
|
|
/* instruction set */
|
|
|
|
#define iACC3 0x06
|
|
|
|
#define iMACINT0 0x04
|
|
|
|
#define iINTERP 0x0e
|
|
|
|
|
|
|
|
#define C_00000000 0x40
|
|
|
|
#define C_00000001 0x41
|
|
|
|
#define C_00000004 0x44
|
|
|
|
#define C_40000000 0x4d
|
|
|
|
/* Audigy constants */
|
|
|
|
#define A_C_00000000 0xc0
|
|
|
|
#define A_C_40000000 0xcd
|
|
|
|
|
|
|
|
/* GPRs */
|
|
|
|
#define FXBUS(x) (0x00 + (x))
|
|
|
|
#define EXTIN(x) (0x10 + (x))
|
|
|
|
#define EXTOUT(x) (0x20 + (x))
|
|
|
|
|
|
|
|
#define GPR(x) (EMU_FXGPREGBASE + (x))
|
|
|
|
#define A_EXTIN(x) (0x40 + (x))
|
|
|
|
#define A_FXBUS(x) (0x00 + (x))
|
|
|
|
#define A_EXTOUT(x) (0x60 + (x))
|
|
|
|
#define A_GPR(x) (EMU_A_FXGPREGBASE + (x))
|
|
|
|
|
|
|
|
/* FX buses */
|
|
|
|
#define FXBUS_PCM_LEFT 0x00
|
|
|
|
#define FXBUS_PCM_RIGHT 0x01
|
|
|
|
#define FXBUS_MIDI_LEFT 0x04
|
|
|
|
#define FXBUS_MIDI_RIGHT 0x05
|
|
|
|
#define FXBUS_MIDI_REVERB 0x0c
|
|
|
|
#define FXBUS_MIDI_CHORUS 0x0d
|
|
|
|
|
|
|
|
/* Inputs */
|
|
|
|
#define EXTIN_AC97_L 0x00
|
|
|
|
#define EXTIN_AC97_R 0x01
|
|
|
|
#define EXTIN_SPDIF_CD_L 0x02
|
|
|
|
#define EXTIN_SPDIF_CD_R 0x03
|
|
|
|
#define EXTIN_TOSLINK_L 0x06
|
|
|
|
#define EXTIN_TOSLINK_R 0x07
|
|
|
|
#define EXTIN_COAX_SPDIF_L 0x0a
|
|
|
|
#define EXTIN_COAX_SPDIF_R 0x0b
|
|
|
|
/* Audigy Inputs */
|
|
|
|
#define A_EXTIN_AC97_L 0x00
|
|
|
|
#define A_EXTIN_AC97_R 0x01
|
|
|
|
|
|
|
|
/* Outputs */
|
|
|
|
#define EXTOUT_AC97_L 0x00
|
|
|
|
#define EXTOUT_AC97_R 0x01
|
|
|
|
#define EXTOUT_TOSLINK_L 0x02
|
|
|
|
#define EXTOUT_TOSLINK_R 0x03
|
|
|
|
#define EXTOUT_AC97_CENTER 0x04
|
|
|
|
#define EXTOUT_AC97_LFE 0x05
|
|
|
|
#define EXTOUT_HEADPHONE_L 0x06
|
|
|
|
#define EXTOUT_HEADPHONE_R 0x07
|
|
|
|
#define EXTOUT_REAR_L 0x08
|
|
|
|
#define EXTOUT_REAR_R 0x09
|
|
|
|
#define EXTOUT_ADC_CAP_L 0x0a
|
|
|
|
#define EXTOUT_ADC_CAP_R 0x0b
|
|
|
|
#define EXTOUT_ACENTER 0x11
|
|
|
|
#define EXTOUT_ALFE 0x12
|
|
|
|
/* Audigy Outputs */
|
|
|
|
#define A_EXTOUT_FRONT_L 0x00
|
|
|
|
#define A_EXTOUT_FRONT_R 0x01
|
|
|
|
#define A_EXTOUT_CENTER 0x02
|
|
|
|
#define A_EXTOUT_LFE 0x03
|
|
|
|
#define A_EXTOUT_HEADPHONE_L 0x04
|
|
|
|
#define A_EXTOUT_HEADPHONE_R 0x05
|
|
|
|
#define A_EXTOUT_REAR_L 0x06
|
|
|
|
#define A_EXTOUT_REAR_R 0x07
|
|
|
|
#define A_EXTOUT_AFRONT_L 0x08
|
|
|
|
#define A_EXTOUT_AFRONT_R 0x09
|
|
|
|
#define A_EXTOUT_ACENTER 0x0a
|
|
|
|
#define A_EXTOUT_ALFE 0x0b
|
|
|
|
#define A_EXTOUT_AREAR_L 0x0e
|
|
|
|
#define A_EXTOUT_AREAR_R 0x0f
|
|
|
|
#define A_EXTOUT_AC97_L 0x10
|
|
|
|
#define A_EXTOUT_AC97_R 0x11
|
|
|
|
#define A_EXTOUT_ADC_CAP_L 0x16
|
|
|
|
#define A_EXTOUT_ADC_CAP_R 0x17
|
2004-01-11 10:30:56 +00:00
|
|
|
|
2000-04-02 07:41:17 +00:00
|
|
|
struct emu_memblk {
|
2000-05-26 02:09:24 +00:00
|
|
|
SLIST_ENTRY(emu_memblk) link;
|
2000-04-02 07:41:17 +00:00
|
|
|
void *buf;
|
2003-02-20 17:31:12 +00:00
|
|
|
bus_addr_t buf_addr;
|
2000-04-02 07:41:17 +00:00
|
|
|
u_int32_t pte_start, pte_size;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct emu_mem {
|
2004-01-11 10:30:56 +00:00
|
|
|
u_int8_t bmap[EMUMAXPAGES / 8];
|
2000-04-04 02:16:15 +00:00
|
|
|
u_int32_t *ptb_pages;
|
2000-04-02 07:41:17 +00:00
|
|
|
void *silent_page;
|
2003-02-20 17:31:12 +00:00
|
|
|
bus_addr_t silent_page_addr;
|
|
|
|
bus_addr_t ptb_pages_addr;
|
2003-04-20 07:43:09 +00:00
|
|
|
SLIST_HEAD(, emu_memblk) blocks;
|
2000-04-02 07:41:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct emu_voice {
|
|
|
|
int vnum;
|
2007-05-27 20:12:51 +00:00
|
|
|
unsigned int b16:1, stereo:1, busy:1, running:1, ismaster:1;
|
2000-04-02 07:41:17 +00:00
|
|
|
int speed;
|
2000-04-05 02:14:26 +00:00
|
|
|
int start, end, vol;
|
2004-01-11 10:30:56 +00:00
|
|
|
int fxrt1; /* FX routing */
|
|
|
|
int fxrt2; /* FX routing (only for audigy) */
|
2000-04-04 02:16:15 +00:00
|
|
|
u_int32_t buf;
|
2000-08-06 18:10:05 +00:00
|
|
|
struct emu_voice *slave;
|
2001-03-24 23:10:29 +00:00
|
|
|
struct pcm_channel *channel;
|
2000-04-02 07:41:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct sc_info;
|
|
|
|
|
|
|
|
/* channel registers */
|
2000-06-13 23:24:40 +00:00
|
|
|
struct sc_pchinfo {
|
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
|
|
|
int spd, fmt, blksz, run;
|
2000-08-06 18:10:05 +00:00
|
|
|
struct emu_voice *master, *slave;
|
2001-03-24 23:10:29 +00:00
|
|
|
struct snd_dbuf *buffer;
|
|
|
|
struct pcm_channel *channel;
|
2000-04-02 07:41:17 +00:00
|
|
|
struct sc_info *parent;
|
|
|
|
};
|
|
|
|
|
2000-06-13 23:24:40 +00:00
|
|
|
struct sc_rchinfo {
|
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
|
|
|
int spd, fmt, run, blksz, num;
|
2000-06-13 23:24:40 +00:00
|
|
|
u_int32_t idxreg, basereg, sizereg, setupreg, irqmask;
|
2001-03-24 23:10:29 +00:00
|
|
|
struct snd_dbuf *buffer;
|
|
|
|
struct pcm_channel *channel;
|
2000-06-13 23:24:40 +00:00
|
|
|
struct sc_info *parent;
|
|
|
|
};
|
|
|
|
|
2000-04-02 07:41:17 +00:00
|
|
|
/* device private data */
|
|
|
|
struct sc_info {
|
|
|
|
device_t dev;
|
2003-04-20 07:43:09 +00:00
|
|
|
u_int32_t type, rev;
|
2004-01-11 10:30:56 +00:00
|
|
|
u_int32_t tos_link:1, APS:1, audigy:1, audigy2:1;
|
|
|
|
u_int32_t addrmask; /* wider if audigy */
|
2000-04-02 07:41:17 +00:00
|
|
|
|
|
|
|
bus_space_tag_t st;
|
|
|
|
bus_space_handle_t sh;
|
|
|
|
bus_dma_tag_t parent_dmat;
|
|
|
|
|
|
|
|
struct resource *reg, *irq;
|
|
|
|
void *ih;
|
2002-11-26 18:16:27 +00:00
|
|
|
struct mtx *lock;
|
2000-04-02 07:41:17 +00:00
|
|
|
|
2001-10-08 06:10:39 +00:00
|
|
|
unsigned int bufsz;
|
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
|
|
|
int timer, timerinterval;
|
2000-06-13 23:24:40 +00:00
|
|
|
int pnum, rnum;
|
2004-01-11 10:30:56 +00:00
|
|
|
int nchans;
|
2000-04-02 07:41:17 +00:00
|
|
|
struct emu_mem mem;
|
|
|
|
struct emu_voice voice[64];
|
2004-01-11 10:30:56 +00:00
|
|
|
struct sc_pchinfo pch[EMU_MAX_CHANS];
|
2000-08-06 18:10:05 +00:00
|
|
|
struct sc_rchinfo rch[3];
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
struct mpu401 *mpu;
|
|
|
|
mpu401_intr_t *mpu_intr;
|
|
|
|
int mputx;
|
2000-04-02 07:41:17 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* prototypes
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* stuff */
|
|
|
|
static int emu_init(struct sc_info *);
|
|
|
|
static void emu_intr(void *);
|
2003-02-20 17:31:12 +00:00
|
|
|
static void *emu_malloc(struct sc_info *sc, u_int32_t sz, bus_addr_t *addr);
|
|
|
|
static void *emu_memalloc(struct sc_info *sc, u_int32_t sz, bus_addr_t *addr);
|
2000-04-02 07:41:17 +00:00
|
|
|
static int emu_memfree(struct sc_info *sc, void *buf);
|
|
|
|
static int emu_memstart(struct sc_info *sc, void *buf);
|
2000-04-03 00:28:43 +00:00
|
|
|
#ifdef EMUDEBUG
|
|
|
|
static void emu_vdump(struct sc_info *sc, struct emu_voice *v);
|
|
|
|
#endif
|
2000-04-02 07:41:17 +00:00
|
|
|
|
|
|
|
/* talk to the card */
|
|
|
|
static u_int32_t emu_rd(struct sc_info *, int, int);
|
|
|
|
static void emu_wr(struct sc_info *, int, u_int32_t, int);
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
2000-08-20 22:18:56 +00:00
|
|
|
static u_int32_t emu_rfmt_ac97[] = {
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
SND_FORMAT(AFMT_S16_LE, 1, 0),
|
|
|
|
SND_FORMAT(AFMT_S16_LE, 2, 0),
|
2000-08-20 22:18:56 +00:00
|
|
|
0
|
|
|
|
};
|
|
|
|
|
|
|
|
static u_int32_t emu_rfmt_mic[] = {
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
SND_FORMAT(AFMT_U8, 1, 0),
|
2000-08-20 22:18:56 +00:00
|
|
|
0
|
|
|
|
};
|
|
|
|
|
|
|
|
static u_int32_t emu_rfmt_efx[] = {
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
SND_FORMAT(AFMT_S16_LE, 2, 0),
|
2000-08-20 22:18:56 +00:00
|
|
|
0
|
|
|
|
};
|
|
|
|
|
2001-03-24 23:10:29 +00:00
|
|
|
static struct pcmchan_caps emu_reccaps[3] = {
|
2000-08-20 22:18:56 +00:00
|
|
|
{8000, 48000, emu_rfmt_ac97, 0},
|
|
|
|
{8000, 8000, emu_rfmt_mic, 0},
|
|
|
|
{48000, 48000, emu_rfmt_efx, 0},
|
2000-04-02 07:41:17 +00:00
|
|
|
};
|
|
|
|
|
2000-08-20 22:18:56 +00:00
|
|
|
static u_int32_t emu_pfmt[] = {
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
SND_FORMAT(AFMT_U8, 1, 0),
|
|
|
|
SND_FORMAT(AFMT_U8, 2, 0),
|
|
|
|
SND_FORMAT(AFMT_S16_LE, 1, 0),
|
|
|
|
SND_FORMAT(AFMT_S16_LE, 2, 0),
|
2000-08-20 22:18:56 +00:00
|
|
|
0
|
2000-04-02 07:41:17 +00:00
|
|
|
};
|
|
|
|
|
2001-03-24 23:10:29 +00:00
|
|
|
static struct pcmchan_caps emu_playcaps = {4000, 48000, emu_pfmt, 0};
|
2000-04-02 07:41:17 +00:00
|
|
|
|
2000-06-13 23:24:40 +00:00
|
|
|
static int adcspeed[8] = {48000, 44100, 32000, 24000, 22050, 16000, 11025, 8000};
|
2004-01-11 10:30:56 +00:00
|
|
|
/* audigy supports 12kHz. */
|
|
|
|
static int audigy_adcspeed[9] = {
|
|
|
|
48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000
|
|
|
|
};
|
2000-06-13 23:24:40 +00:00
|
|
|
|
2000-04-02 07:41:17 +00:00
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
/* Hardware */
|
|
|
|
static u_int32_t
|
|
|
|
emu_rd(struct sc_info *sc, int regno, int size)
|
|
|
|
{
|
|
|
|
switch (size) {
|
|
|
|
case 1:
|
|
|
|
return bus_space_read_1(sc->st, sc->sh, regno);
|
|
|
|
case 2:
|
|
|
|
return bus_space_read_2(sc->st, sc->sh, regno);
|
|
|
|
case 4:
|
|
|
|
return bus_space_read_4(sc->st, sc->sh, regno);
|
|
|
|
default:
|
|
|
|
return 0xffffffff;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
emu_wr(struct sc_info *sc, int regno, u_int32_t data, int size)
|
|
|
|
{
|
|
|
|
switch (size) {
|
|
|
|
case 1:
|
|
|
|
bus_space_write_1(sc->st, sc->sh, regno, data);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
bus_space_write_2(sc->st, sc->sh, regno, data);
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
bus_space_write_4(sc->st, sc->sh, regno, data);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static u_int32_t
|
|
|
|
emu_rdptr(struct sc_info *sc, int chn, int reg)
|
|
|
|
{
|
2003-04-20 08:37:29 +00:00
|
|
|
u_int32_t ptr, val, mask, size, offset;
|
|
|
|
|
2012-01-03 21:04:54 +00:00
|
|
|
ptr = ((reg << 16) & sc->addrmask) | (chn & EMU_PTR_CHNO_MASK);
|
|
|
|
emu_wr(sc, EMU_PTR, ptr, 4);
|
|
|
|
val = emu_rd(sc, EMU_DATA, 4);
|
2003-04-20 08:37:29 +00:00
|
|
|
if (reg & 0xff000000) {
|
|
|
|
size = (reg >> 24) & 0x3f;
|
|
|
|
offset = (reg >> 16) & 0x1f;
|
|
|
|
mask = ((1 << size) - 1) << offset;
|
|
|
|
val &= mask;
|
2000-04-02 07:41:17 +00:00
|
|
|
val >>= offset;
|
|
|
|
}
|
2003-04-20 08:37:29 +00:00
|
|
|
return val;
|
2000-04-02 07:41:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
emu_wrptr(struct sc_info *sc, int chn, int reg, u_int32_t data)
|
|
|
|
{
|
2003-04-20 08:37:29 +00:00
|
|
|
u_int32_t ptr, mask, size, offset;
|
|
|
|
|
2012-01-03 21:04:54 +00:00
|
|
|
ptr = ((reg << 16) & sc->addrmask) | (chn & EMU_PTR_CHNO_MASK);
|
|
|
|
emu_wr(sc, EMU_PTR, ptr, 4);
|
2003-04-20 08:37:29 +00:00
|
|
|
if (reg & 0xff000000) {
|
|
|
|
size = (reg >> 24) & 0x3f;
|
|
|
|
offset = (reg >> 16) & 0x1f;
|
|
|
|
mask = ((1 << size) - 1) << offset;
|
2000-04-02 07:41:17 +00:00
|
|
|
data <<= offset;
|
2003-04-20 08:37:29 +00:00
|
|
|
data &= mask;
|
2012-01-03 21:04:54 +00:00
|
|
|
data |= emu_rd(sc, EMU_DATA, 4) & ~mask;
|
2000-04-02 07:41:17 +00:00
|
|
|
}
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wr(sc, EMU_DATA, data, 4);
|
2000-04-02 07:41:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
emu_wrefx(struct sc_info *sc, unsigned int pc, unsigned int data)
|
|
|
|
{
|
2012-01-03 21:04:54 +00:00
|
|
|
pc += sc->audigy ? EMU_A_MICROCODEBASE : EMU_MICROCODEBASE;
|
2004-01-11 10:30:56 +00:00
|
|
|
emu_wrptr(sc, 0, pc, data);
|
2000-04-02 07:41:17 +00:00
|
|
|
}
|
|
|
|
|
2000-12-18 01:36:41 +00:00
|
|
|
/* -------------------------------------------------------------------- */
|
2000-08-06 18:10:05 +00:00
|
|
|
/* ac97 codec */
|
2001-03-24 23:10:29 +00:00
|
|
|
/* no locking needed */
|
2000-12-18 01:36:41 +00:00
|
|
|
|
|
|
|
static int
|
|
|
|
emu_rdcd(kobj_t obj, void *devinfo, int regno)
|
2000-08-06 18:10:05 +00:00
|
|
|
{
|
|
|
|
struct sc_info *sc = (struct sc_info *)devinfo;
|
|
|
|
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wr(sc, EMU_AC97ADDR, regno, 1);
|
|
|
|
return emu_rd(sc, EMU_AC97DATA, 2);
|
2000-08-06 18:10:05 +00:00
|
|
|
}
|
|
|
|
|
2000-12-18 01:36:41 +00:00
|
|
|
static int
|
|
|
|
emu_wrcd(kobj_t obj, void *devinfo, int regno, u_int32_t data)
|
2000-08-06 18:10:05 +00:00
|
|
|
{
|
|
|
|
struct sc_info *sc = (struct sc_info *)devinfo;
|
|
|
|
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wr(sc, EMU_AC97ADDR, regno, 1);
|
|
|
|
emu_wr(sc, EMU_AC97DATA, data, 2);
|
2000-12-18 01:36:41 +00:00
|
|
|
return 0;
|
2000-08-06 18:10:05 +00:00
|
|
|
}
|
|
|
|
|
2000-12-18 01:36:41 +00:00
|
|
|
static kobj_method_t emu_ac97_methods[] = {
|
2003-04-20 07:43:09 +00:00
|
|
|
KOBJMETHOD(ac97_read, emu_rdcd),
|
|
|
|
KOBJMETHOD(ac97_write, emu_wrcd),
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
KOBJMETHOD_END
|
2000-12-18 01:36:41 +00:00
|
|
|
};
|
|
|
|
AC97_DECLARE(emu_ac97);
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
2000-08-06 18:10:05 +00:00
|
|
|
/* stuff */
|
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
|
|
|
static int
|
|
|
|
emu_settimer(struct sc_info *sc)
|
|
|
|
{
|
|
|
|
struct sc_pchinfo *pch;
|
|
|
|
struct sc_rchinfo *rch;
|
|
|
|
int i, tmp, rate;
|
|
|
|
|
|
|
|
rate = 0;
|
2004-01-11 10:30:56 +00:00
|
|
|
for (i = 0; i < sc->nchans; i++) {
|
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
|
|
|
pch = &sc->pch[i];
|
2001-10-08 06:10:39 +00:00
|
|
|
if (pch->buffer) {
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
tmp = (pch->spd * sndbuf_getalign(pch->buffer))
|
2004-01-11 10:30:56 +00:00
|
|
|
/ pch->blksz;
|
2001-10-08 06:10:39 +00:00
|
|
|
if (tmp > rate)
|
|
|
|
rate = tmp;
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < 3; i++) {
|
|
|
|
rch = &sc->rch[i];
|
2001-10-08 06:10:39 +00:00
|
|
|
if (rch->buffer) {
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
tmp = (rch->spd * sndbuf_getalign(rch->buffer))
|
2004-01-11 10:30:56 +00:00
|
|
|
/ rch->blksz;
|
2001-10-08 06:10:39 +00:00
|
|
|
if (tmp > rate)
|
|
|
|
rate = tmp;
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
RANGE(rate, 48, 9600);
|
|
|
|
sc->timerinterval = 48000 / rate;
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wr(sc, EMU_TIMER, sc->timerinterval & 0x03ff, 2);
|
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
|
|
|
|
|
|
|
return sc->timerinterval;
|
|
|
|
}
|
|
|
|
|
2000-08-06 18:10:05 +00:00
|
|
|
static int
|
|
|
|
emu_enatimer(struct sc_info *sc, int go)
|
|
|
|
{
|
|
|
|
u_int32_t x;
|
|
|
|
if (go) {
|
|
|
|
if (sc->timer++ == 0) {
|
2012-01-03 21:04:54 +00:00
|
|
|
x = emu_rd(sc, EMU_INTE, 4);
|
|
|
|
x |= EMU_INTE_INTERTIMERENB;
|
|
|
|
emu_wr(sc, EMU_INTE, x, 4);
|
2000-08-06 18:10:05 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
sc->timer = 0;
|
2012-01-03 21:04:54 +00:00
|
|
|
x = emu_rd(sc, EMU_INTE, 4);
|
|
|
|
x &= ~EMU_INTE_INTERTIMERENB;
|
|
|
|
emu_wr(sc, EMU_INTE, x, 4);
|
2000-08-06 18:10:05 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2000-04-02 07:41:17 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
emu_enastop(struct sc_info *sc, char channel, int enable)
|
|
|
|
{
|
2012-01-03 21:04:54 +00:00
|
|
|
int reg = (channel & 0x20) ? EMU_SOLEH : EMU_SOLEL;
|
2000-04-02 07:41:17 +00:00
|
|
|
channel &= 0x1f;
|
|
|
|
reg |= 1 << 24;
|
|
|
|
reg |= channel << 16;
|
|
|
|
emu_wrptr(sc, 0, reg, enable);
|
|
|
|
}
|
|
|
|
|
2000-06-13 23:24:40 +00:00
|
|
|
static int
|
|
|
|
emu_recval(int speed) {
|
|
|
|
int val;
|
|
|
|
|
|
|
|
val = 0;
|
|
|
|
while (val < 7 && speed < adcspeed[val])
|
|
|
|
val++;
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
2004-01-11 10:30:56 +00:00
|
|
|
static int
|
|
|
|
audigy_recval(int speed) {
|
|
|
|
int val;
|
|
|
|
|
|
|
|
val = 0;
|
|
|
|
while (val < 8 && speed < audigy_adcspeed[val])
|
|
|
|
val++;
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
2000-04-02 07:41:17 +00:00
|
|
|
static u_int32_t
|
|
|
|
emu_rate_to_pitch(u_int32_t rate)
|
|
|
|
{
|
|
|
|
static u_int32_t logMagTable[128] = {
|
|
|
|
0x00000, 0x02dfc, 0x05b9e, 0x088e6, 0x0b5d6, 0x0e26f, 0x10eb3, 0x13aa2,
|
|
|
|
0x1663f, 0x1918a, 0x1bc84, 0x1e72e, 0x2118b, 0x23b9a, 0x2655d, 0x28ed5,
|
|
|
|
0x2b803, 0x2e0e8, 0x30985, 0x331db, 0x359eb, 0x381b6, 0x3a93d, 0x3d081,
|
|
|
|
0x3f782, 0x41e42, 0x444c1, 0x46b01, 0x49101, 0x4b6c4, 0x4dc49, 0x50191,
|
|
|
|
0x5269e, 0x54b6f, 0x57006, 0x59463, 0x5b888, 0x5dc74, 0x60029, 0x623a7,
|
|
|
|
0x646ee, 0x66a00, 0x68cdd, 0x6af86, 0x6d1fa, 0x6f43c, 0x7164b, 0x73829,
|
|
|
|
0x759d4, 0x77b4f, 0x79c9a, 0x7bdb5, 0x7dea1, 0x7ff5e, 0x81fed, 0x8404e,
|
|
|
|
0x86082, 0x88089, 0x8a064, 0x8c014, 0x8df98, 0x8fef1, 0x91e20, 0x93d26,
|
|
|
|
0x95c01, 0x97ab4, 0x9993e, 0x9b79f, 0x9d5d9, 0x9f3ec, 0xa11d8, 0xa2f9d,
|
|
|
|
0xa4d3c, 0xa6ab5, 0xa8808, 0xaa537, 0xac241, 0xadf26, 0xafbe7, 0xb1885,
|
|
|
|
0xb3500, 0xb5157, 0xb6d8c, 0xb899f, 0xba58f, 0xbc15e, 0xbdd0c, 0xbf899,
|
|
|
|
0xc1404, 0xc2f50, 0xc4a7b, 0xc6587, 0xc8073, 0xc9b3f, 0xcb5ed, 0xcd07c,
|
|
|
|
0xceaec, 0xd053f, 0xd1f73, 0xd398a, 0xd5384, 0xd6d60, 0xd8720, 0xda0c3,
|
|
|
|
0xdba4a, 0xdd3b4, 0xded03, 0xe0636, 0xe1f4e, 0xe384a, 0xe512c, 0xe69f3,
|
|
|
|
0xe829f, 0xe9b31, 0xeb3a9, 0xecc08, 0xee44c, 0xefc78, 0xf148a, 0xf2c83,
|
|
|
|
0xf4463, 0xf5c2a, 0xf73da, 0xf8b71, 0xfa2f0, 0xfba57, 0xfd1a7, 0xfe8df
|
|
|
|
};
|
|
|
|
static char logSlopeTable[128] = {
|
|
|
|
0x5c, 0x5c, 0x5b, 0x5a, 0x5a, 0x59, 0x58, 0x58,
|
|
|
|
0x57, 0x56, 0x56, 0x55, 0x55, 0x54, 0x53, 0x53,
|
|
|
|
0x52, 0x52, 0x51, 0x51, 0x50, 0x50, 0x4f, 0x4f,
|
|
|
|
0x4e, 0x4d, 0x4d, 0x4d, 0x4c, 0x4c, 0x4b, 0x4b,
|
|
|
|
0x4a, 0x4a, 0x49, 0x49, 0x48, 0x48, 0x47, 0x47,
|
|
|
|
0x47, 0x46, 0x46, 0x45, 0x45, 0x45, 0x44, 0x44,
|
|
|
|
0x43, 0x43, 0x43, 0x42, 0x42, 0x42, 0x41, 0x41,
|
|
|
|
0x41, 0x40, 0x40, 0x40, 0x3f, 0x3f, 0x3f, 0x3e,
|
|
|
|
0x3e, 0x3e, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c, 0x3c,
|
|
|
|
0x3b, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39,
|
|
|
|
0x39, 0x39, 0x39, 0x38, 0x38, 0x38, 0x38, 0x37,
|
|
|
|
0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x36, 0x35,
|
|
|
|
0x35, 0x35, 0x35, 0x34, 0x34, 0x34, 0x34, 0x34,
|
|
|
|
0x33, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x32,
|
|
|
|
0x32, 0x31, 0x31, 0x31, 0x31, 0x31, 0x30, 0x30,
|
|
|
|
0x30, 0x30, 0x30, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f
|
|
|
|
};
|
|
|
|
int i;
|
|
|
|
|
|
|
|
if (rate == 0)
|
|
|
|
return 0; /* Bail out if no leading "1" */
|
|
|
|
rate *= 11185; /* Scale 48000 to 0x20002380 */
|
|
|
|
for (i = 31; i > 0; i--) {
|
|
|
|
if (rate & 0x80000000) { /* Detect leading "1" */
|
|
|
|
return (((u_int32_t) (i - 15) << 20) +
|
2003-04-20 08:37:29 +00:00
|
|
|
logMagTable[0x7f & (rate >> 24)] +
|
|
|
|
(0x7f & (rate >> 17)) *
|
|
|
|
logSlopeTable[0x7f & (rate >> 24)]);
|
2000-04-02 07:41:17 +00:00
|
|
|
}
|
|
|
|
rate <<= 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0; /* Should never reach this point */
|
|
|
|
}
|
|
|
|
|
2000-08-06 18:10:05 +00:00
|
|
|
static u_int32_t
|
|
|
|
emu_rate_to_linearpitch(u_int32_t rate)
|
|
|
|
{
|
|
|
|
rate = (rate << 8) / 375;
|
|
|
|
return (rate >> 1) + (rate & 1);
|
|
|
|
}
|
|
|
|
|
2000-04-02 07:41:17 +00:00
|
|
|
static struct emu_voice *
|
|
|
|
emu_valloc(struct sc_info *sc)
|
|
|
|
{
|
|
|
|
struct emu_voice *v;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
v = NULL;
|
|
|
|
for (i = 0; i < 64 && sc->voice[i].busy; i++);
|
|
|
|
if (i < 64) {
|
|
|
|
v = &sc->voice[i];
|
|
|
|
v->busy = 1;
|
|
|
|
}
|
|
|
|
return v;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2000-08-06 18:10:05 +00:00
|
|
|
emu_vinit(struct sc_info *sc, struct emu_voice *m, struct emu_voice *s,
|
2001-03-24 23:10:29 +00:00
|
|
|
u_int32_t sz, struct snd_dbuf *b)
|
2000-04-02 07:41:17 +00:00
|
|
|
{
|
|
|
|
void *buf;
|
2003-02-20 17:31:12 +00:00
|
|
|
bus_addr_t tmp_addr;
|
2000-04-02 07:41:17 +00:00
|
|
|
|
2003-02-20 17:31:12 +00:00
|
|
|
buf = emu_memalloc(sc, sz, &tmp_addr);
|
2000-04-02 07:41:17 +00:00
|
|
|
if (buf == NULL)
|
|
|
|
return -1;
|
2001-03-24 23:10:29 +00:00
|
|
|
if (b != NULL)
|
|
|
|
sndbuf_setup(b, buf, sz);
|
2000-04-02 07:41:17 +00:00
|
|
|
m->start = emu_memstart(sc, buf) * EMUPAGESIZE;
|
2000-04-04 02:16:15 +00:00
|
|
|
m->end = m->start + sz;
|
2000-04-05 02:14:26 +00:00
|
|
|
m->channel = NULL;
|
2000-04-02 07:41:17 +00:00
|
|
|
m->speed = 0;
|
|
|
|
m->b16 = 0;
|
|
|
|
m->stereo = 0;
|
2000-08-06 18:10:05 +00:00
|
|
|
m->running = 0;
|
2000-04-05 02:14:26 +00:00
|
|
|
m->ismaster = 1;
|
|
|
|
m->vol = 0xff;
|
2003-02-20 17:31:12 +00:00
|
|
|
m->buf = tmp_addr;
|
2000-04-02 07:41:17 +00:00
|
|
|
m->slave = s;
|
2004-01-11 10:30:56 +00:00
|
|
|
if (sc->audigy) {
|
Fix the order of the stereo channels (left <-> right).
From the PR:
---snip---
I think I have found the change which reversed the channels.
Revision 1.44 of emu10k1.c, which added Audigy support, has the line
emu_wrptr(sc, v->vnum, FXRT, 0xd01c0000);
replaced with the following lines:
if (sc->audigy) {
emu_wrptr(sc, v->vnum, A_FXRT1, v->fxrt1);
emu_wrptr(sc, v->vnum, A_FXRT2, v->fxrt2);
emu_wrptr(sc, v->vnum, A_SENDAMOUNTS, 0);
}
else
emu_wrptr(sc, v->vnum, FXRT, v->fxrt1 << 16);
where v->fxrt1 << 16 == 0xd10c0000
I don't have Audigy, so I'm not sure if the problem affects Audigy cards
too. The order of the channels can't be tested by just altering mixer
settings. Here's a small program to test if the channels are reversed on
your sound card:
#include <sys/soundcard.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int fd = open("/dev/dsp", O_WRONLY), format = AFMT_S16_LE;
int channels = 2, rate = 22050, i;
/* 450 Hz sine wave on left channel, right channel silent */
unsigned char samples[] = {0, 0, 0, 0, 94, 16, 0, 0, 120, 32, 0, 0,
9, 48, 0, 0, 208, 62, 0, 0, 143, 76, 0, 0, 12, 89, 0, 0, 19, 100,
0, 0, 117, 109, 0, 0, 11, 117, 0, 0, 182, 122, 0, 0, 92, 126, 0,
0, 239, 127, 0, 0, 105, 127, 0, 0, 202, 124, 0, 0, 32, 120, 0, 0,
124, 113, 0, 0, 251, 104, 0, 0, 193, 94, 0, 0, 249, 82, 0, 0,
212, 69, 0, 0, 138, 55, 0, 0, 85, 40, 0, 0, 120, 24, 0, 0, 51, 8,
0, 0, 205, 247, 0, 0, 136, 231, 0, 0, 171, 215, 0, 0, 118, 200,
0, 0, 44, 186, 0, 0, 7, 173, 0, 0, 63, 161, 0, 0, 5, 151, 0, 0,
132, 142, 0, 0, 224, 135, 0, 0, 54, 131, 0, 0, 151, 128, 0, 0,
17, 128, 0, 0, 164, 129, 0, 0, 74, 133, 0, 0, 245, 138, 0, 0,
139, 146, 0, 0, 237, 155, 0, 0, 244, 166, 0, 0, 113, 179, 0, 0,
48, 193, 0, 0, 247, 207, 0, 0, 136, 223, 0, 0, 162, 239, 0, 0};
ioctl(fd, SNDCTL_DSP_SETFMT,&format);
ioctl(fd, SNDCTL_DSP_CHANNELS,&channels);
ioctl(fd, SNDCTL_DSP_SPEED,&rate);
for(i=0;i<500;i++)
write(fd, &samples, sizeof(samples));
write(fd, &samples, 2); /* swap channels */
for(i=0;i<500;i++)
write(fd, &samples, sizeof(samples));
return 0;
}
You should hear a sound on the left channel followed by a sound on the
right channel. If you hear a sound on the right channel first, the
channels are reversed.
---snip---
Owners of an audigy card should verify if it DTRT and report back.
Noticed by: Matthias Buelow <mkb@mukappabeta.de>
Submitted by: Juha-Matti Tilli <juhis@nallukka.net>
PR: 72221
2005-12-28 17:57:36 +00:00
|
|
|
m->fxrt1 = FXBUS_MIDI_CHORUS | FXBUS_PCM_RIGHT << 8 |
|
|
|
|
FXBUS_PCM_LEFT << 16 | FXBUS_MIDI_REVERB << 24;
|
2004-01-11 10:30:56 +00:00
|
|
|
m->fxrt2 = 0x3f3f3f3f; /* No effects on second route */
|
|
|
|
} else {
|
Fix the order of the stereo channels (left <-> right).
From the PR:
---snip---
I think I have found the change which reversed the channels.
Revision 1.44 of emu10k1.c, which added Audigy support, has the line
emu_wrptr(sc, v->vnum, FXRT, 0xd01c0000);
replaced with the following lines:
if (sc->audigy) {
emu_wrptr(sc, v->vnum, A_FXRT1, v->fxrt1);
emu_wrptr(sc, v->vnum, A_FXRT2, v->fxrt2);
emu_wrptr(sc, v->vnum, A_SENDAMOUNTS, 0);
}
else
emu_wrptr(sc, v->vnum, FXRT, v->fxrt1 << 16);
where v->fxrt1 << 16 == 0xd10c0000
I don't have Audigy, so I'm not sure if the problem affects Audigy cards
too. The order of the channels can't be tested by just altering mixer
settings. Here's a small program to test if the channels are reversed on
your sound card:
#include <sys/soundcard.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char **argv)
{
int fd = open("/dev/dsp", O_WRONLY), format = AFMT_S16_LE;
int channels = 2, rate = 22050, i;
/* 450 Hz sine wave on left channel, right channel silent */
unsigned char samples[] = {0, 0, 0, 0, 94, 16, 0, 0, 120, 32, 0, 0,
9, 48, 0, 0, 208, 62, 0, 0, 143, 76, 0, 0, 12, 89, 0, 0, 19, 100,
0, 0, 117, 109, 0, 0, 11, 117, 0, 0, 182, 122, 0, 0, 92, 126, 0,
0, 239, 127, 0, 0, 105, 127, 0, 0, 202, 124, 0, 0, 32, 120, 0, 0,
124, 113, 0, 0, 251, 104, 0, 0, 193, 94, 0, 0, 249, 82, 0, 0,
212, 69, 0, 0, 138, 55, 0, 0, 85, 40, 0, 0, 120, 24, 0, 0, 51, 8,
0, 0, 205, 247, 0, 0, 136, 231, 0, 0, 171, 215, 0, 0, 118, 200,
0, 0, 44, 186, 0, 0, 7, 173, 0, 0, 63, 161, 0, 0, 5, 151, 0, 0,
132, 142, 0, 0, 224, 135, 0, 0, 54, 131, 0, 0, 151, 128, 0, 0,
17, 128, 0, 0, 164, 129, 0, 0, 74, 133, 0, 0, 245, 138, 0, 0,
139, 146, 0, 0, 237, 155, 0, 0, 244, 166, 0, 0, 113, 179, 0, 0,
48, 193, 0, 0, 247, 207, 0, 0, 136, 223, 0, 0, 162, 239, 0, 0};
ioctl(fd, SNDCTL_DSP_SETFMT,&format);
ioctl(fd, SNDCTL_DSP_CHANNELS,&channels);
ioctl(fd, SNDCTL_DSP_SPEED,&rate);
for(i=0;i<500;i++)
write(fd, &samples, sizeof(samples));
write(fd, &samples, 2); /* swap channels */
for(i=0;i<500;i++)
write(fd, &samples, sizeof(samples));
return 0;
}
You should hear a sound on the left channel followed by a sound on the
right channel. If you hear a sound on the right channel first, the
channels are reversed.
---snip---
Owners of an audigy card should verify if it DTRT and report back.
Noticed by: Matthias Buelow <mkb@mukappabeta.de>
Submitted by: Juha-Matti Tilli <juhis@nallukka.net>
PR: 72221
2005-12-28 17:57:36 +00:00
|
|
|
m->fxrt1 = FXBUS_MIDI_CHORUS | FXBUS_PCM_RIGHT << 4 |
|
|
|
|
FXBUS_PCM_LEFT << 8 | FXBUS_MIDI_REVERB << 12;
|
2004-01-11 10:30:56 +00:00
|
|
|
m->fxrt2 = 0;
|
|
|
|
}
|
|
|
|
|
2000-04-02 07:41:17 +00:00
|
|
|
if (s != NULL) {
|
|
|
|
s->start = m->start;
|
|
|
|
s->end = m->end;
|
|
|
|
s->channel = NULL;
|
|
|
|
s->speed = 0;
|
|
|
|
s->b16 = 0;
|
|
|
|
s->stereo = 0;
|
2000-08-06 18:10:05 +00:00
|
|
|
s->running = 0;
|
2000-04-05 02:14:26 +00:00
|
|
|
s->ismaster = 0;
|
|
|
|
s->vol = m->vol;
|
2000-04-04 02:16:15 +00:00
|
|
|
s->buf = m->buf;
|
2004-01-11 10:30:56 +00:00
|
|
|
s->fxrt1 = m->fxrt1;
|
|
|
|
s->fxrt2 = m->fxrt2;
|
2000-04-02 07:41:17 +00:00
|
|
|
s->slave = NULL;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2000-06-13 23:24:40 +00:00
|
|
|
emu_vsetup(struct sc_pchinfo *ch)
|
2000-04-02 07:41:17 +00:00
|
|
|
{
|
|
|
|
struct emu_voice *v = ch->master;
|
|
|
|
|
|
|
|
if (ch->fmt) {
|
2003-04-20 07:43:09 +00:00
|
|
|
v->b16 = (ch->fmt & AFMT_16BIT) ? 1 : 0;
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
v->stereo = (AFMT_CHANNEL(ch->fmt) > 1) ? 1 : 0;
|
2000-04-02 07:41:17 +00:00
|
|
|
if (v->slave != NULL) {
|
|
|
|
v->slave->b16 = v->b16;
|
|
|
|
v->slave->stereo = v->stereo;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (ch->spd) {
|
|
|
|
v->speed = ch->spd;
|
|
|
|
if (v->slave != NULL)
|
|
|
|
v->slave->speed = v->speed;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
emu_vwrite(struct sc_info *sc, struct emu_voice *v)
|
|
|
|
{
|
2000-08-06 18:10:05 +00:00
|
|
|
int s;
|
|
|
|
int l, r, x, y;
|
|
|
|
u_int32_t sa, ea, start, val, silent_page;
|
2000-04-02 07:41:17 +00:00
|
|
|
|
2003-04-20 07:43:09 +00:00
|
|
|
s = (v->stereo ? 1 : 0) + (v->b16 ? 1 : 0);
|
2000-08-06 18:10:05 +00:00
|
|
|
|
2000-04-02 07:41:17 +00:00
|
|
|
sa = v->start >> s;
|
|
|
|
ea = v->end >> s;
|
2000-08-06 18:10:05 +00:00
|
|
|
|
|
|
|
l = r = x = y = v->vol;
|
2000-04-02 07:41:17 +00:00
|
|
|
if (v->stereo) {
|
2003-04-20 07:43:09 +00:00
|
|
|
l = v->ismaster ? l : 0;
|
|
|
|
r = v->ismaster ? 0 : r;
|
2000-04-02 07:41:17 +00:00
|
|
|
}
|
|
|
|
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_CPF, v->stereo ? EMU_CHAN_CPF_STEREO_MASK : 0);
|
2003-04-20 07:43:09 +00:00
|
|
|
val = v->stereo ? 28 : 30;
|
|
|
|
val *= v->b16 ? 1 : 2;
|
2000-08-06 18:10:05 +00:00
|
|
|
start = sa + val;
|
|
|
|
|
2004-01-11 10:30:56 +00:00
|
|
|
if (sc->audigy) {
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, v->vnum, EMU_A_CHAN_FXRT1, v->fxrt1);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_A_CHAN_FXRT2, v->fxrt2);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_A_CHAN_SENDAMOUNTS, 0);
|
2004-01-11 10:30:56 +00:00
|
|
|
}
|
|
|
|
else
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_FXRT, v->fxrt1 << 16);
|
2000-04-02 07:41:17 +00:00
|
|
|
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_PTRX, (x << 8) | r);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_DSL, ea | (y << 24));
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_PSST, sa | (l << 24));
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_CCCA, start | (v->b16 ? 0 : EMU_CHAN_CCCA_8BITSELECT));
|
2000-04-02 07:41:17 +00:00
|
|
|
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_Z1, 0);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_Z2, 0);
|
2000-04-02 07:41:17 +00:00
|
|
|
|
2004-01-11 10:30:56 +00:00
|
|
|
silent_page = ((u_int32_t)(sc->mem.silent_page_addr) << 1)
|
2012-01-03 21:04:54 +00:00
|
|
|
| EMU_CHAN_MAP_PTI_MASK;
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_MAPA, silent_page);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_MAPB, silent_page);
|
|
|
|
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_CVCF, EMU_CHAN_CVCF_CURRFILTER_MASK);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_VTFT, EMU_CHAN_VTFT_FILTERTARGET_MASK);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_ATKHLDM, 0);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_DCYSUSM, EMU_CHAN_DCYSUSM_DECAYTIME_MASK);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_LFOVAL1, 0x8000);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_LFOVAL2, 0x8000);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_FMMOD, 0);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_TREMFRQ, 0);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_FM2FRQ2, 0);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_ENVVAL, 0x8000);
|
|
|
|
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_ATKHLDV,
|
|
|
|
EMU_CHAN_ATKHLDV_HOLDTIME_MASK | EMU_CHAN_ATKHLDV_ATTACKTIME_MASK);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_ENVVOL, 0x8000);
|
|
|
|
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_PEFE_FILTERAMOUNT, 0x7f);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_PEFE_PITCHAMOUNT, 0);
|
2000-04-05 02:14:26 +00:00
|
|
|
|
|
|
|
if (v->slave != NULL)
|
|
|
|
emu_vwrite(sc, v->slave);
|
2000-04-02 07:41:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
emu_vtrigger(struct sc_info *sc, struct emu_voice *v, int go)
|
|
|
|
{
|
2000-08-06 18:10:05 +00:00
|
|
|
u_int32_t pitch_target, initial_pitch;
|
|
|
|
u_int32_t cra, cs, ccis;
|
|
|
|
u_int32_t sample, i;
|
|
|
|
|
2000-04-02 07:41:17 +00:00
|
|
|
if (go) {
|
2000-08-06 18:10:05 +00:00
|
|
|
cra = 64;
|
2003-04-20 07:43:09 +00:00
|
|
|
cs = v->stereo ? 4 : 2;
|
|
|
|
ccis = v->stereo ? 28 : 30;
|
|
|
|
ccis *= v->b16 ? 1 : 2;
|
|
|
|
sample = v->b16 ? 0x00000000 : 0x80808080;
|
2000-08-06 18:10:05 +00:00
|
|
|
|
|
|
|
for (i = 0; i < cs; i++)
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_CD0 + i, sample);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_CCR_CACHEINVALIDSIZE, 0);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_CCR_READADDRESS, cra);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_CCR_CACHEINVALIDSIZE, ccis);
|
|
|
|
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_IFATN, 0xff00);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_VTFT, 0xffffffff);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_CVCF, 0xffffffff);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_DCYSUSV, 0x00007f7f);
|
2000-08-06 18:10:05 +00:00
|
|
|
emu_enastop(sc, v->vnum, 0);
|
|
|
|
|
|
|
|
pitch_target = emu_rate_to_linearpitch(v->speed);
|
|
|
|
initial_pitch = emu_rate_to_pitch(v->speed) >> 8;
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_PTRX_PITCHTARGET, pitch_target);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_CPF_PITCH, pitch_target);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_IP, initial_pitch);
|
2000-04-02 07:41:17 +00:00
|
|
|
} else {
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_PTRX_PITCHTARGET, 0);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_CPF_PITCH, 0);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_IFATN, 0xffff);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_VTFT, 0x0000ffff);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_CVCF, 0x0000ffff);
|
|
|
|
emu_wrptr(sc, v->vnum, EMU_CHAN_IP, 0);
|
2000-08-06 18:10:05 +00:00
|
|
|
emu_enastop(sc, v->vnum, 1);
|
2000-04-02 07:41:17 +00:00
|
|
|
}
|
2000-04-05 02:14:26 +00:00
|
|
|
if (v->slave != NULL)
|
|
|
|
emu_vtrigger(sc, v->slave, go);
|
2000-04-02 07:41:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
emu_vpos(struct sc_info *sc, struct emu_voice *v)
|
|
|
|
{
|
2000-06-13 23:24:40 +00:00
|
|
|
int s, ptr;
|
|
|
|
|
2003-04-20 07:43:09 +00:00
|
|
|
s = (v->b16 ? 1 : 0) + (v->stereo ? 1 : 0);
|
2012-01-03 21:04:54 +00:00
|
|
|
ptr = (emu_rdptr(sc, v->vnum, EMU_CHAN_CCCA_CURRADDR) - (v->start >> s)) << s;
|
2000-08-06 18:10:05 +00:00
|
|
|
return ptr & ~0x0000001f;
|
2000-04-02 07:41:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef EMUDEBUG
|
|
|
|
static void
|
|
|
|
emu_vdump(struct sc_info *sc, struct emu_voice *v)
|
|
|
|
{
|
2003-04-20 09:07:14 +00:00
|
|
|
char *regname[] = {
|
|
|
|
"cpf", "ptrx", "cvcf", "vtft", "z2", "z1", "psst", "dsl",
|
|
|
|
"ccca", "ccr", "clp", "fxrt", "mapa", "mapb", NULL, NULL,
|
|
|
|
"envvol", "atkhldv", "dcysusv", "lfoval1",
|
|
|
|
"envval", "atkhldm", "dcysusm", "lfoval2",
|
|
|
|
"ip", "ifatn", "pefe", "fmmod", "tremfrq", "fmfrq2",
|
|
|
|
"tempenv"
|
|
|
|
};
|
2004-01-11 10:30:56 +00:00
|
|
|
char *regname2[] = {
|
|
|
|
"mudata1", "mustat1", "mudata2", "mustat2",
|
|
|
|
"fxwc1", "fxwc2", "spdrate", NULL, NULL,
|
|
|
|
NULL, NULL, NULL, "fxrt2", "sndamnt", "fxrt1",
|
|
|
|
NULL, NULL
|
|
|
|
};
|
2000-04-02 07:41:17 +00:00
|
|
|
int i, x;
|
|
|
|
|
|
|
|
printf("voice number %d\n", v->vnum);
|
|
|
|
for (i = 0, x = 0; i <= 0x1e; i++) {
|
|
|
|
if (regname[i] == NULL)
|
|
|
|
continue;
|
|
|
|
printf("%s\t[%08x]", regname[i], emu_rdptr(sc, v->vnum, i));
|
2003-04-20 07:43:09 +00:00
|
|
|
printf("%s", (x == 2) ? "\n" : "\t");
|
2000-04-02 07:41:17 +00:00
|
|
|
x++;
|
|
|
|
if (x > 2)
|
|
|
|
x = 0;
|
|
|
|
}
|
2004-01-11 10:30:56 +00:00
|
|
|
|
|
|
|
/* Print out audigy extra registers */
|
|
|
|
if (sc->audigy) {
|
|
|
|
for (i = 0; i <= 0xe; i++) {
|
|
|
|
if (regname2[i] == NULL)
|
|
|
|
continue;
|
|
|
|
printf("%s\t[%08x]", regname2[i],
|
|
|
|
emu_rdptr(sc, v->vnum, i + 0x70));
|
|
|
|
printf("%s", (x == 2)? "\n" : "\t");
|
|
|
|
x++;
|
|
|
|
if (x > 2)
|
|
|
|
x = 0;
|
|
|
|
}
|
|
|
|
}
|
2000-04-02 07:41:17 +00:00
|
|
|
printf("\n\n");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* channel interface */
|
2000-12-18 01:36:41 +00:00
|
|
|
static void *
|
2004-01-11 10:30:56 +00:00
|
|
|
emupchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
|
|
|
|
struct pcm_channel *c, int dir)
|
2000-04-02 07:41:17 +00:00
|
|
|
{
|
|
|
|
struct sc_info *sc = devinfo;
|
2000-06-13 23:24:40 +00:00
|
|
|
struct sc_pchinfo *ch;
|
2001-03-24 23:10:29 +00:00
|
|
|
void *r;
|
2000-04-02 07:41:17 +00:00
|
|
|
|
2000-06-13 23:24:40 +00:00
|
|
|
KASSERT(dir == PCMDIR_PLAY, ("emupchan_init: bad direction"));
|
|
|
|
ch = &sc->pch[sc->pnum++];
|
2000-04-02 07:41:17 +00:00
|
|
|
ch->buffer = b;
|
|
|
|
ch->parent = sc;
|
|
|
|
ch->channel = c;
|
2001-10-08 06:10:39 +00:00
|
|
|
ch->blksz = sc->bufsz / 2;
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
ch->fmt = SND_FORMAT(AFMT_U8, 1, 0);
|
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
|
|
|
ch->spd = 8000;
|
2001-03-24 23:10:29 +00:00
|
|
|
snd_mtxlock(sc->lock);
|
2000-04-02 07:41:17 +00:00
|
|
|
ch->master = emu_valloc(sc);
|
|
|
|
ch->slave = emu_valloc(sc);
|
2001-03-24 23:10:29 +00:00
|
|
|
snd_mtxunlock(sc->lock);
|
2004-01-11 10:30:56 +00:00
|
|
|
r = (emu_vinit(sc, ch->master, ch->slave, sc->bufsz, ch->buffer))
|
|
|
|
? NULL : ch;
|
2001-03-24 23:10:29 +00:00
|
|
|
|
|
|
|
return r;
|
2000-04-02 07:41:17 +00:00
|
|
|
}
|
|
|
|
|
2000-09-01 20:09:24 +00:00
|
|
|
static int
|
2000-12-18 01:36:41 +00:00
|
|
|
emupchan_free(kobj_t obj, void *data)
|
2000-09-01 20:09:24 +00:00
|
|
|
{
|
|
|
|
struct sc_pchinfo *ch = data;
|
|
|
|
struct sc_info *sc = ch->parent;
|
2001-03-24 23:10:29 +00:00
|
|
|
int r;
|
|
|
|
|
|
|
|
snd_mtxlock(sc->lock);
|
|
|
|
r = emu_memfree(sc, sndbuf_getbuf(ch->buffer));
|
|
|
|
snd_mtxunlock(sc->lock);
|
2000-09-01 20:09:24 +00:00
|
|
|
|
2001-03-24 23:10:29 +00:00
|
|
|
return r;
|
2000-09-01 20:09:24 +00:00
|
|
|
}
|
|
|
|
|
2000-04-02 07:41:17 +00:00
|
|
|
static int
|
2000-12-18 01:36:41 +00:00
|
|
|
emupchan_setformat(kobj_t obj, void *data, u_int32_t format)
|
2000-04-02 07:41:17 +00:00
|
|
|
{
|
2000-06-13 23:24:40 +00:00
|
|
|
struct sc_pchinfo *ch = data;
|
2000-04-02 07:41:17 +00:00
|
|
|
|
|
|
|
ch->fmt = format;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
static u_int32_t
|
2000-12-18 01:36:41 +00:00
|
|
|
emupchan_setspeed(kobj_t obj, void *data, u_int32_t speed)
|
2000-04-02 07:41:17 +00:00
|
|
|
{
|
2000-06-13 23:24:40 +00:00
|
|
|
struct sc_pchinfo *ch = data;
|
2000-04-02 07:41:17 +00:00
|
|
|
|
|
|
|
ch->spd = speed;
|
|
|
|
return ch->spd;
|
|
|
|
}
|
|
|
|
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
static u_int32_t
|
2000-12-18 01:36:41 +00:00
|
|
|
emupchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
|
2000-04-02 07:41:17 +00:00
|
|
|
{
|
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
|
|
|
struct sc_pchinfo *ch = data;
|
|
|
|
struct sc_info *sc = ch->parent;
|
|
|
|
int irqrate, blksz;
|
|
|
|
|
|
|
|
ch->blksz = blocksize;
|
2001-03-24 23:10:29 +00:00
|
|
|
snd_mtxlock(sc->lock);
|
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
|
|
|
emu_settimer(sc);
|
|
|
|
irqrate = 48000 / sc->timerinterval;
|
2001-03-24 23:10:29 +00:00
|
|
|
snd_mtxunlock(sc->lock);
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
blksz = (ch->spd * sndbuf_getalign(ch->buffer)) / irqrate;
|
2000-04-02 07:41:17 +00:00
|
|
|
return blocksize;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2000-12-18 01:36:41 +00:00
|
|
|
emupchan_trigger(kobj_t obj, void *data, int go)
|
2000-04-02 07:41:17 +00:00
|
|
|
{
|
2000-06-13 23:24:40 +00:00
|
|
|
struct sc_pchinfo *ch = data;
|
2000-09-01 20:09:24 +00:00
|
|
|
struct sc_info *sc = ch->parent;
|
2000-04-02 07:41:17 +00:00
|
|
|
|
2007-06-11 00:49:46 +00:00
|
|
|
if (!PCMTRIG_COMMON(go))
|
2000-05-26 21:15:47 +00:00
|
|
|
return 0;
|
|
|
|
|
2001-03-24 23:10:29 +00:00
|
|
|
snd_mtxlock(sc->lock);
|
2000-04-02 07:41:17 +00:00
|
|
|
if (go == PCMTRIG_START) {
|
|
|
|
emu_vsetup(ch);
|
|
|
|
emu_vwrite(sc, ch->master);
|
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
|
|
|
emu_settimer(sc);
|
2000-08-06 18:10:05 +00:00
|
|
|
emu_enatimer(sc, 1);
|
2000-04-02 07:41:17 +00:00
|
|
|
#ifdef EMUDEBUG
|
|
|
|
printf("start [%d bit, %s, %d hz]\n",
|
2003-04-20 07:43:09 +00:00
|
|
|
ch->master->b16 ? 16 : 8,
|
|
|
|
ch->master->stereo ? "stereo" : "mono",
|
2000-04-02 07:41:17 +00:00
|
|
|
ch->master->speed);
|
|
|
|
emu_vdump(sc, ch->master);
|
|
|
|
emu_vdump(sc, ch->slave);
|
|
|
|
#endif
|
|
|
|
}
|
2003-04-20 07:43:09 +00:00
|
|
|
ch->run = (go == PCMTRIG_START) ? 1 : 0;
|
2000-06-13 23:24:40 +00:00
|
|
|
emu_vtrigger(sc, ch->master, ch->run);
|
2001-03-24 23:10:29 +00:00
|
|
|
snd_mtxunlock(sc->lock);
|
2000-04-02 07:41:17 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
static u_int32_t
|
2000-12-18 01:36:41 +00:00
|
|
|
emupchan_getptr(kobj_t obj, void *data)
|
2000-04-02 07:41:17 +00:00
|
|
|
{
|
2000-06-13 23:24:40 +00:00
|
|
|
struct sc_pchinfo *ch = data;
|
2000-04-02 07:41:17 +00:00
|
|
|
struct sc_info *sc = ch->parent;
|
2001-03-24 23:10:29 +00:00
|
|
|
int r;
|
|
|
|
|
|
|
|
snd_mtxlock(sc->lock);
|
|
|
|
r = emu_vpos(sc, ch->master);
|
|
|
|
snd_mtxunlock(sc->lock);
|
2000-04-02 07:41:17 +00:00
|
|
|
|
2001-03-24 23:10:29 +00:00
|
|
|
return r;
|
2000-04-02 07:41:17 +00:00
|
|
|
}
|
|
|
|
|
2001-03-24 23:10:29 +00:00
|
|
|
static struct pcmchan_caps *
|
2000-12-18 01:36:41 +00:00
|
|
|
emupchan_getcaps(kobj_t obj, void *data)
|
2000-06-13 23:24:40 +00:00
|
|
|
{
|
|
|
|
return &emu_playcaps;
|
|
|
|
}
|
|
|
|
|
2000-12-18 01:36:41 +00:00
|
|
|
static kobj_method_t emupchan_methods[] = {
|
2003-04-20 07:43:09 +00:00
|
|
|
KOBJMETHOD(channel_init, emupchan_init),
|
|
|
|
KOBJMETHOD(channel_free, emupchan_free),
|
|
|
|
KOBJMETHOD(channel_setformat, emupchan_setformat),
|
|
|
|
KOBJMETHOD(channel_setspeed, emupchan_setspeed),
|
|
|
|
KOBJMETHOD(channel_setblocksize, emupchan_setblocksize),
|
|
|
|
KOBJMETHOD(channel_trigger, emupchan_trigger),
|
|
|
|
KOBJMETHOD(channel_getptr, emupchan_getptr),
|
|
|
|
KOBJMETHOD(channel_getcaps, emupchan_getcaps),
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
KOBJMETHOD_END
|
2000-12-18 01:36:41 +00:00
|
|
|
};
|
|
|
|
CHANNEL_DECLARE(emupchan);
|
|
|
|
|
2000-06-13 23:24:40 +00:00
|
|
|
/* channel interface */
|
|
|
|
static void *
|
2004-01-11 10:30:56 +00:00
|
|
|
emurchan_init(kobj_t obj, void *devinfo, struct snd_dbuf *b,
|
|
|
|
struct pcm_channel *c, int dir)
|
2000-06-13 23:24:40 +00:00
|
|
|
{
|
|
|
|
struct sc_info *sc = devinfo;
|
|
|
|
struct sc_rchinfo *ch;
|
|
|
|
|
2000-08-06 18:10:05 +00:00
|
|
|
KASSERT(dir == PCMDIR_REC, ("emurchan_init: bad direction"));
|
2000-06-13 23:24:40 +00:00
|
|
|
ch = &sc->rch[sc->rnum];
|
|
|
|
ch->buffer = b;
|
|
|
|
ch->parent = sc;
|
|
|
|
ch->channel = c;
|
2001-10-08 06:10:39 +00:00
|
|
|
ch->blksz = sc->bufsz / 2;
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
ch->fmt = SND_FORMAT(AFMT_U8, 1, 0);
|
2000-06-13 23:24:40 +00:00
|
|
|
ch->spd = 8000;
|
|
|
|
ch->num = sc->rnum;
|
|
|
|
switch(sc->rnum) {
|
|
|
|
case 0:
|
2012-01-03 21:04:54 +00:00
|
|
|
ch->idxreg = sc->audigy ? EMU_A_ADCIDX : EMU_ADCIDX;
|
|
|
|
ch->basereg = EMU_ADCBA;
|
|
|
|
ch->sizereg = EMU_ADCBS;
|
|
|
|
ch->setupreg = EMU_ADCCR;
|
|
|
|
ch->irqmask = EMU_INTE_ADCBUFENABLE;
|
2000-06-13 23:24:40 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 1:
|
2012-01-03 21:04:54 +00:00
|
|
|
ch->idxreg = EMU_FXIDX;
|
|
|
|
ch->basereg = EMU_FXBA;
|
|
|
|
ch->sizereg = EMU_FXBS;
|
|
|
|
ch->setupreg = EMU_FXWC;
|
|
|
|
ch->irqmask = EMU_INTE_EFXBUFENABLE;
|
2000-06-13 23:24:40 +00:00
|
|
|
break;
|
2001-10-08 06:10:39 +00:00
|
|
|
|
|
|
|
case 2:
|
2012-01-03 21:04:54 +00:00
|
|
|
ch->idxreg = EMU_MICIDX;
|
|
|
|
ch->basereg = EMU_MICBA;
|
|
|
|
ch->sizereg = EMU_MICBS;
|
2001-10-08 06:10:39 +00:00
|
|
|
ch->setupreg = 0;
|
2012-01-03 21:04:54 +00:00
|
|
|
ch->irqmask = EMU_INTE_MICBUFENABLE;
|
2001-10-08 06:10:39 +00:00
|
|
|
break;
|
2000-06-13 23:24:40 +00:00
|
|
|
}
|
|
|
|
sc->rnum++;
|
2007-04-18 18:26:41 +00:00
|
|
|
if (sndbuf_alloc(ch->buffer, sc->parent_dmat, 0, sc->bufsz) != 0)
|
2000-06-13 23:24:40 +00:00
|
|
|
return NULL;
|
|
|
|
else {
|
2001-03-24 23:10:29 +00:00
|
|
|
snd_mtxlock(sc->lock);
|
2003-02-20 17:31:12 +00:00
|
|
|
emu_wrptr(sc, 0, ch->basereg, sndbuf_getbufaddr(ch->buffer));
|
2000-06-13 23:24:40 +00:00
|
|
|
emu_wrptr(sc, 0, ch->sizereg, 0); /* off */
|
2001-03-24 23:10:29 +00:00
|
|
|
snd_mtxunlock(sc->lock);
|
2000-06-13 23:24:40 +00:00
|
|
|
return ch;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2000-12-18 01:36:41 +00:00
|
|
|
emurchan_setformat(kobj_t obj, void *data, u_int32_t format)
|
2000-06-13 23:24:40 +00:00
|
|
|
{
|
|
|
|
struct sc_rchinfo *ch = data;
|
|
|
|
|
|
|
|
ch->fmt = format;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
static u_int32_t
|
2000-12-18 01:36:41 +00:00
|
|
|
emurchan_setspeed(kobj_t obj, void *data, u_int32_t speed)
|
2000-06-13 23:24:40 +00:00
|
|
|
{
|
|
|
|
struct sc_rchinfo *ch = data;
|
|
|
|
|
2004-01-11 10:30:56 +00:00
|
|
|
if (ch->num == 0) {
|
|
|
|
if (ch->parent->audigy)
|
|
|
|
speed = audigy_adcspeed[audigy_recval(speed)];
|
|
|
|
else
|
|
|
|
speed = adcspeed[emu_recval(speed)];
|
|
|
|
}
|
2000-06-13 23:24:40 +00:00
|
|
|
if (ch->num == 1)
|
|
|
|
speed = 48000;
|
2001-10-08 06:10:39 +00:00
|
|
|
if (ch->num == 2)
|
|
|
|
speed = 8000;
|
2000-06-13 23:24:40 +00:00
|
|
|
ch->spd = speed;
|
|
|
|
return ch->spd;
|
|
|
|
}
|
|
|
|
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
static u_int32_t
|
2000-12-18 01:36:41 +00:00
|
|
|
emurchan_setblocksize(kobj_t obj, void *data, u_int32_t blocksize)
|
2000-06-13 23:24:40 +00:00
|
|
|
{
|
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
|
|
|
struct sc_rchinfo *ch = data;
|
|
|
|
struct sc_info *sc = ch->parent;
|
|
|
|
int irqrate, blksz;
|
|
|
|
|
|
|
|
ch->blksz = blocksize;
|
2001-03-24 23:10:29 +00:00
|
|
|
snd_mtxlock(sc->lock);
|
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
|
|
|
emu_settimer(sc);
|
|
|
|
irqrate = 48000 / sc->timerinterval;
|
2001-03-24 23:10:29 +00:00
|
|
|
snd_mtxunlock(sc->lock);
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
blksz = (ch->spd * sndbuf_getalign(ch->buffer)) / irqrate;
|
2000-06-13 23:24:40 +00:00
|
|
|
return blocksize;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* semantic note: must start at beginning of buffer */
|
|
|
|
static int
|
2000-12-18 01:36:41 +00:00
|
|
|
emurchan_trigger(kobj_t obj, void *data, int go)
|
2000-06-13 23:24:40 +00:00
|
|
|
{
|
|
|
|
struct sc_rchinfo *ch = data;
|
|
|
|
struct sc_info *sc = ch->parent;
|
2001-10-08 06:10:39 +00:00
|
|
|
u_int32_t val, sz;
|
|
|
|
|
2007-06-11 00:49:46 +00:00
|
|
|
if (!PCMTRIG_COMMON(go))
|
|
|
|
return 0;
|
|
|
|
|
2001-10-08 06:10:39 +00:00
|
|
|
switch(sc->bufsz) {
|
|
|
|
case 4096:
|
2012-01-03 21:04:54 +00:00
|
|
|
sz = EMU_RECBS_BUFSIZE_4096;
|
2001-10-08 06:10:39 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 8192:
|
2012-01-03 21:04:54 +00:00
|
|
|
sz = EMU_RECBS_BUFSIZE_8192;
|
2001-10-08 06:10:39 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 16384:
|
2012-01-03 21:04:54 +00:00
|
|
|
sz = EMU_RECBS_BUFSIZE_16384;
|
2001-10-08 06:10:39 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 32768:
|
2012-01-03 21:04:54 +00:00
|
|
|
sz = EMU_RECBS_BUFSIZE_32768;
|
2001-10-08 06:10:39 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 65536:
|
2012-01-03 21:04:54 +00:00
|
|
|
sz = EMU_RECBS_BUFSIZE_65536;
|
2001-10-08 06:10:39 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2012-01-03 21:04:54 +00:00
|
|
|
sz = EMU_RECBS_BUFSIZE_4096;
|
2001-10-08 06:10:39 +00:00
|
|
|
}
|
2000-06-13 23:24:40 +00:00
|
|
|
|
2001-03-24 23:10:29 +00:00
|
|
|
snd_mtxlock(sc->lock);
|
2000-06-13 23:24:40 +00:00
|
|
|
switch(go) {
|
|
|
|
case PCMTRIG_START:
|
|
|
|
ch->run = 1;
|
2001-10-08 06:10:39 +00:00
|
|
|
emu_wrptr(sc, 0, ch->sizereg, sz);
|
2000-06-13 23:24:40 +00:00
|
|
|
if (ch->num == 0) {
|
2004-01-11 10:30:56 +00:00
|
|
|
if (sc->audigy) {
|
2012-01-11 21:03:54 +00:00
|
|
|
val = EMU_A_ADCCR_LCHANENABLE;
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
if (AFMT_CHANNEL(ch->fmt) > 1)
|
2012-01-11 21:03:54 +00:00
|
|
|
val |= EMU_A_ADCCR_RCHANENABLE;
|
2004-01-11 10:30:56 +00:00
|
|
|
val |= audigy_recval(ch->spd);
|
|
|
|
} else {
|
2012-01-03 21:04:54 +00:00
|
|
|
val = EMU_ADCCR_LCHANENABLE;
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
if (AFMT_CHANNEL(ch->fmt) > 1)
|
2012-01-03 21:04:54 +00:00
|
|
|
val |= EMU_ADCCR_RCHANENABLE;
|
2004-01-11 10:30:56 +00:00
|
|
|
val |= emu_recval(ch->spd);
|
|
|
|
}
|
|
|
|
|
2001-10-08 06:10:39 +00:00
|
|
|
emu_wrptr(sc, 0, ch->setupreg, 0);
|
2000-06-13 23:24:40 +00:00
|
|
|
emu_wrptr(sc, 0, ch->setupreg, val);
|
|
|
|
}
|
2012-01-03 21:04:54 +00:00
|
|
|
val = emu_rd(sc, EMU_INTE, 4);
|
2000-06-13 23:24:40 +00:00
|
|
|
val |= ch->irqmask;
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wr(sc, EMU_INTE, val, 4);
|
2000-06-13 23:24:40 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case PCMTRIG_STOP:
|
|
|
|
case PCMTRIG_ABORT:
|
|
|
|
ch->run = 0;
|
|
|
|
emu_wrptr(sc, 0, ch->sizereg, 0);
|
|
|
|
if (ch->setupreg)
|
|
|
|
emu_wrptr(sc, 0, ch->setupreg, 0);
|
2012-01-03 21:04:54 +00:00
|
|
|
val = emu_rd(sc, EMU_INTE, 4);
|
2000-06-13 23:24:40 +00:00
|
|
|
val &= ~ch->irqmask;
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wr(sc, EMU_INTE, val, 4);
|
2000-06-13 23:24:40 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
case PCMTRIG_EMLDMAWR:
|
|
|
|
case PCMTRIG_EMLDMARD:
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2001-03-24 23:10:29 +00:00
|
|
|
snd_mtxunlock(sc->lock);
|
2000-06-13 23:24:40 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
static u_int32_t
|
2000-12-18 01:36:41 +00:00
|
|
|
emurchan_getptr(kobj_t obj, void *data)
|
2000-06-13 23:24:40 +00:00
|
|
|
{
|
|
|
|
struct sc_rchinfo *ch = data;
|
|
|
|
struct sc_info *sc = ch->parent;
|
2001-03-24 23:10:29 +00:00
|
|
|
int r;
|
|
|
|
|
|
|
|
snd_mtxlock(sc->lock);
|
|
|
|
r = emu_rdptr(sc, 0, ch->idxreg) & 0x0000ffff;
|
|
|
|
snd_mtxunlock(sc->lock);
|
2000-06-13 23:24:40 +00:00
|
|
|
|
2001-03-24 23:10:29 +00:00
|
|
|
return r;
|
2000-06-13 23:24:40 +00:00
|
|
|
}
|
|
|
|
|
2001-03-24 23:10:29 +00:00
|
|
|
static struct pcmchan_caps *
|
2000-12-18 01:36:41 +00:00
|
|
|
emurchan_getcaps(kobj_t obj, void *data)
|
2000-04-02 07:41:17 +00:00
|
|
|
{
|
2000-06-13 23:24:40 +00:00
|
|
|
struct sc_rchinfo *ch = data;
|
2000-04-02 07:41:17 +00:00
|
|
|
|
2000-06-13 23:24:40 +00:00
|
|
|
return &emu_reccaps[ch->num];
|
2000-04-02 07:41:17 +00:00
|
|
|
}
|
|
|
|
|
2001-10-08 06:10:39 +00:00
|
|
|
static kobj_method_t emurchan_methods[] = {
|
2003-04-20 07:43:09 +00:00
|
|
|
KOBJMETHOD(channel_init, emurchan_init),
|
|
|
|
KOBJMETHOD(channel_setformat, emurchan_setformat),
|
|
|
|
KOBJMETHOD(channel_setspeed, emurchan_setspeed),
|
|
|
|
KOBJMETHOD(channel_setblocksize, emurchan_setblocksize),
|
|
|
|
KOBJMETHOD(channel_trigger, emurchan_trigger),
|
|
|
|
KOBJMETHOD(channel_getptr, emurchan_getptr),
|
|
|
|
KOBJMETHOD(channel_getcaps, emurchan_getcaps),
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
KOBJMETHOD_END
|
2001-10-08 06:10:39 +00:00
|
|
|
};
|
|
|
|
CHANNEL_DECLARE(emurchan);
|
|
|
|
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
static unsigned char
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
emu_mread(struct mpu401 *arg, void *sc, int reg)
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
{
|
|
|
|
unsigned int d;
|
|
|
|
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
d = emu_rd((struct sc_info *)sc, 0x18 + reg, 1);
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
emu_mwrite(struct mpu401 *arg, void *sc, int reg, unsigned char b)
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
{
|
|
|
|
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
emu_wr((struct sc_info *)sc, 0x18 + reg, b, 1);
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
emu_muninit(struct mpu401 *arg, void *cookie)
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
{
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
struct sc_info *sc = cookie;
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
|
|
|
|
snd_mtxlock(sc->lock);
|
|
|
|
sc->mpu_intr = 0;
|
|
|
|
snd_mtxunlock(sc->lock);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static kobj_method_t emu_mpu_methods[] = {
|
|
|
|
KOBJMETHOD(mpufoi_read, emu_mread),
|
|
|
|
KOBJMETHOD(mpufoi_write, emu_mwrite),
|
|
|
|
KOBJMETHOD(mpufoi_uninit, emu_muninit),
|
Sound Mega-commit. Expect further cleanup until code freeze.
For a slightly thorough explaination, please refer to
[1] http://people.freebsd.org/~ariff/SOUND_4.TXT.html .
Summary of changes includes:
1 Volume Per-Channel (vpc). Provides private / standalone volume control
unique per-stream pcm channel without touching master volume / pcm.
Applications can directly use SNDCTL_DSP_[GET|SET][PLAY|REC]VOL, or for
backwards compatibility, SOUND_MIXER_PCM through the opened dsp device
instead of /dev/mixer. Special "bypass" mode is enabled through
/dev/mixer which will automatically detect if the adjustment is made
through /dev/mixer and forward its request to this private volume
controller. Changes to this volume object will not interfere with
other channels.
Requirements:
- SNDCTL_DSP_[GET|SET][PLAY|REC]_VOL are newer ioctls (OSSv4) which
require specific application modifications (preferred).
- No modifications required for using bypass mode, so applications
like mplayer or xmms should work out of the box.
Kernel hints:
- hint.pcm.%d.vpc (0 = disable vpc).
Kernel sysctls:
- hw.snd.vpc_mixer_bypass (default: 1). Enable or disable /dev/mixer
bypass mode.
- hw.snd.vpc_autoreset (default: 1). By default, closing/opening
/dev/dsp will reset the volume back to 0 db gain/attenuation.
Setting this to 0 will preserve its settings across device
closing/opening.
- hw.snd.vpc_reset (default: 0). Panic/reset button to reset all
volume settings back to 0 db.
- hw.snd.vpc_0db (default: 45). 0 db relative to linear mixer value.
2 High quality fixed-point Bandlimited SINC sampling rate converter,
based on Julius O'Smith's Digital Audio Resampling -
http://ccrma.stanford.edu/~jos/resample/. It includes a filter design
script written in awk (the clumsiest joke I've ever written)
- 100% 32bit fixed-point, 64bit accumulator.
- Possibly among the fastest (if not fastest) of its kind.
- Resampling quality is tunable, either runtime or during kernel
compilation (FEEDER_RATE_PRESETS).
- Quality can be further customized during kernel compilation by
defining FEEDER_RATE_PRESETS in /etc/make.conf.
Kernel sysctls:
- hw.snd.feeder_rate_quality.
0 - Zero-order Hold (ZOH). Fastest, bad quality.
1 - Linear Interpolation (LINEAR). Slightly slower than ZOH,
better quality but still does not eliminate aliasing.
2 - (and above) - Sinc Interpolation(SINC). Best quality. SINC
quality always start from 2 and above.
Rough quality comparisons:
- http://people.freebsd.org/~ariff/z_comparison/
3 Bit-perfect mode. Bypasses all feeder/dsp effects. Pure sound will be
directly fed into the hardware.
4 Parametric (compile time) Software Equalizer (Bass/Treble mixer). Can
be customized by defining FEEDER_EQ_PRESETS in /etc/make.conf.
5 Transparent/Adaptive Virtual Channel. Now you don't have to disable
vchans in order to make digital format pass through. It also makes
vchans more dynamic by choosing a better format/rate among all the
concurrent streams, which means that dev.pcm.X.play.vchanformat/rate
becomes sort of optional.
6 Exclusive Stream, with special open() mode O_EXCL. This will "mute"
other concurrent vchan streams and only allow a single channel with
O_EXCL set to keep producing sound.
Other Changes:
* most feeder_* stuffs are compilable in userland. Let's not
speculate whether we should go all out for it (save that for
FreeBSD 16.0-RELEASE).
* kobj signature fixups, thanks to Andriy Gapon <avg@freebsd.org>
* pull out channel mixing logic out of vchan.c and create its own
feeder_mixer for world justice.
* various refactoring here and there, for good or bad.
* activation of few more OSSv4 ioctls() (see [1] above).
* opt_snd.h for possible compile time configuration:
(mostly for debugging purposes, don't try these at home)
SND_DEBUG
SND_DIAGNOSTIC
SND_FEEDER_MULTIFORMAT
SND_FEEDER_FULL_MULTIFORMAT
SND_FEEDER_RATE_HP
SND_PCM_64
SND_OLDSTEREO
Manual page updates are on the way.
Tested by: joel, Olivier SMEDTS <olivier at gid0 d org>, too many
unsung / unnamed heroes.
2009-06-07 19:12:08 +00:00
|
|
|
KOBJMETHOD_END
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
};
|
|
|
|
|
2006-07-15 20:08:32 +00:00
|
|
|
static DEFINE_CLASS(emu_mpu, emu_mpu_methods, 0);
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
|
|
|
|
static void
|
|
|
|
emu_intr2(void *p)
|
|
|
|
{
|
|
|
|
struct sc_info *sc = (struct sc_info *)p;
|
|
|
|
|
|
|
|
if (sc->mpu_intr)
|
|
|
|
(sc->mpu_intr)(sc->mpu);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
emu_midiattach(struct sc_info *sc)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2012-01-03 21:04:54 +00:00
|
|
|
i = emu_rd(sc, EMU_INTE, 4);
|
|
|
|
i |= EMU_INTE_MIDIRXENABLE;
|
|
|
|
emu_wr(sc, EMU_INTE, i, 4);
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
|
|
|
|
sc->mpu = mpu401_init(&emu_mpu_class, sc, emu_intr2, &sc->mpu_intr);
|
|
|
|
}
|
2001-10-08 06:10:39 +00:00
|
|
|
/* -------------------------------------------------------------------- */
|
2000-04-02 07:41:17 +00:00
|
|
|
/* The interrupt handler */
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
|
2000-04-02 07:41:17 +00:00
|
|
|
static void
|
2004-06-04 16:42:33 +00:00
|
|
|
emu_intr(void *data)
|
2000-04-02 07:41:17 +00:00
|
|
|
{
|
2004-06-04 16:42:33 +00:00
|
|
|
struct sc_info *sc = data;
|
2000-08-06 18:10:05 +00:00
|
|
|
u_int32_t stat, ack, i, x;
|
2000-04-02 07:41:17 +00:00
|
|
|
|
2004-06-04 16:42:33 +00:00
|
|
|
snd_mtxlock(sc->lock);
|
2000-06-13 23:24:40 +00:00
|
|
|
while (1) {
|
2012-01-03 21:04:54 +00:00
|
|
|
stat = emu_rd(sc, EMU_IPR, 4);
|
2000-06-13 23:24:40 +00:00
|
|
|
if (stat == 0)
|
|
|
|
break;
|
|
|
|
ack = 0;
|
2000-04-02 07:41:17 +00:00
|
|
|
|
|
|
|
/* process irq */
|
2012-01-03 21:04:54 +00:00
|
|
|
if (stat & EMU_IPR_INTERVALTIMER)
|
|
|
|
ack |= EMU_IPR_INTERVALTIMER;
|
2000-08-06 18:10:05 +00:00
|
|
|
|
2012-01-03 21:04:54 +00:00
|
|
|
if (stat & (EMU_IPR_ADCBUFFULL | EMU_IPR_ADCBUFHALFFULL))
|
|
|
|
ack |= stat & (EMU_IPR_ADCBUFFULL | EMU_IPR_ADCBUFHALFFULL);
|
2004-06-04 16:42:33 +00:00
|
|
|
|
2012-01-03 21:04:54 +00:00
|
|
|
if (stat & (EMU_IPR_EFXBUFFULL | EMU_IPR_EFXBUFHALFFULL))
|
|
|
|
ack |= stat & (EMU_IPR_EFXBUFFULL | EMU_IPR_EFXBUFHALFFULL);
|
2004-06-04 16:42:33 +00:00
|
|
|
|
2012-01-03 21:04:54 +00:00
|
|
|
if (stat & (EMU_IPR_MICBUFFULL | EMU_IPR_MICBUFHALFFULL))
|
|
|
|
ack |= stat & (EMU_IPR_MICBUFFULL | EMU_IPR_MICBUFHALFFULL);
|
2004-06-04 16:42:33 +00:00
|
|
|
|
2012-01-03 21:04:54 +00:00
|
|
|
if (stat & EMU_PCIERROR) {
|
|
|
|
ack |= EMU_PCIERROR;
|
2000-06-13 23:24:40 +00:00
|
|
|
device_printf(sc->dev, "pci error\n");
|
2000-08-06 18:10:05 +00:00
|
|
|
/* we still get an nmi with ecc ram even if we ack this */
|
|
|
|
}
|
2012-01-03 21:04:54 +00:00
|
|
|
if (stat & EMU_IPR_RATETRCHANGE) {
|
|
|
|
ack |= EMU_IPR_RATETRCHANGE;
|
2004-01-11 10:30:56 +00:00
|
|
|
#ifdef EMUDEBUG
|
|
|
|
device_printf(sc->dev,
|
|
|
|
"sample rate tracker lock status change\n");
|
|
|
|
#endif
|
2000-06-13 23:24:40 +00:00
|
|
|
}
|
|
|
|
|
2012-01-03 21:04:54 +00:00
|
|
|
if (stat & EMU_IPR_MIDIRECVBUFE)
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
if (sc->mpu_intr) {
|
|
|
|
(sc->mpu_intr)(sc->mpu);
|
2012-01-03 21:04:54 +00:00
|
|
|
ack |= EMU_IPR_MIDIRECVBUFE | EMU_IPR_MIDITRANSBUFE;
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
}
|
2000-06-13 23:24:40 +00:00
|
|
|
if (stat & ~ack)
|
2004-06-04 16:42:33 +00:00
|
|
|
device_printf(sc->dev, "dodgy irq: %x (harmless)\n",
|
|
|
|
stat & ~ack);
|
2000-06-13 23:24:40 +00:00
|
|
|
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wr(sc, EMU_IPR, stat, 4);
|
2004-06-04 16:42:33 +00:00
|
|
|
|
|
|
|
if (ack) {
|
|
|
|
snd_mtxunlock(sc->lock);
|
|
|
|
|
2012-01-03 21:04:54 +00:00
|
|
|
if (ack & EMU_IPR_INTERVALTIMER) {
|
2004-06-04 16:42:33 +00:00
|
|
|
x = 0;
|
|
|
|
for (i = 0; i < sc->nchans; i++) {
|
|
|
|
if (sc->pch[i].run) {
|
|
|
|
x = 1;
|
|
|
|
chn_intr(sc->pch[i].channel);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (x == 0)
|
|
|
|
emu_enatimer(sc, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-01-03 21:04:54 +00:00
|
|
|
if (ack & (EMU_IPR_ADCBUFFULL | EMU_IPR_ADCBUFHALFFULL)) {
|
2004-06-04 16:42:33 +00:00
|
|
|
if (sc->rch[0].channel)
|
|
|
|
chn_intr(sc->rch[0].channel);
|
|
|
|
}
|
2012-01-03 21:04:54 +00:00
|
|
|
if (ack & (EMU_IPR_EFXBUFFULL | EMU_IPR_EFXBUFHALFFULL)) {
|
2004-06-04 16:42:33 +00:00
|
|
|
if (sc->rch[1].channel)
|
|
|
|
chn_intr(sc->rch[1].channel);
|
|
|
|
}
|
2012-01-03 21:04:54 +00:00
|
|
|
if (ack & (EMU_IPR_MICBUFFULL | EMU_IPR_MICBUFHALFFULL)) {
|
2004-06-04 16:42:33 +00:00
|
|
|
if (sc->rch[2].channel)
|
|
|
|
chn_intr(sc->rch[2].channel);
|
|
|
|
}
|
|
|
|
|
|
|
|
snd_mtxlock(sc->lock);
|
|
|
|
}
|
2000-06-13 23:24:40 +00:00
|
|
|
}
|
2004-06-04 16:42:33 +00:00
|
|
|
snd_mtxunlock(sc->lock);
|
2000-04-02 07:41:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* -------------------------------------------------------------------- */
|
|
|
|
|
2000-06-13 23:24:40 +00:00
|
|
|
static void
|
|
|
|
emu_setmap(void *arg, bus_dma_segment_t *segs, int nseg, int error)
|
|
|
|
{
|
2003-02-26 16:11:18 +00:00
|
|
|
bus_addr_t *phys = arg;
|
2000-06-13 23:24:40 +00:00
|
|
|
|
2003-04-20 07:43:09 +00:00
|
|
|
*phys = error ? 0 : (bus_addr_t)segs->ds_addr;
|
2000-06-13 23:24:40 +00:00
|
|
|
|
|
|
|
if (bootverbose) {
|
|
|
|
printf("emu: setmap (%lx, %lx), nseg=%d, error=%d\n",
|
2003-04-20 08:37:29 +00:00
|
|
|
(unsigned long)segs->ds_addr, (unsigned long)segs->ds_len,
|
|
|
|
nseg, error);
|
2000-06-13 23:24:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-04-02 07:41:17 +00:00
|
|
|
static void *
|
2003-02-20 17:31:12 +00:00
|
|
|
emu_malloc(struct sc_info *sc, u_int32_t sz, bus_addr_t *addr)
|
2000-04-02 07:41:17 +00:00
|
|
|
{
|
2003-02-20 17:31:12 +00:00
|
|
|
void *buf;
|
2000-04-02 07:41:17 +00:00
|
|
|
bus_dmamap_t map;
|
|
|
|
|
2003-02-20 17:31:12 +00:00
|
|
|
*addr = 0;
|
2000-04-02 07:41:17 +00:00
|
|
|
if (bus_dmamem_alloc(sc->parent_dmat, &buf, BUS_DMA_NOWAIT, &map))
|
|
|
|
return NULL;
|
2003-02-20 17:31:12 +00:00
|
|
|
if (bus_dmamap_load(sc->parent_dmat, map, buf, sz, emu_setmap, addr, 0)
|
2003-02-26 16:11:18 +00:00
|
|
|
|| !*addr)
|
2000-06-13 23:24:40 +00:00
|
|
|
return NULL;
|
2000-04-02 07:41:17 +00:00
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
emu_free(struct sc_info *sc, void *buf)
|
|
|
|
{
|
|
|
|
bus_dmamem_free(sc->parent_dmat, buf, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void *
|
2003-02-20 17:31:12 +00:00
|
|
|
emu_memalloc(struct sc_info *sc, u_int32_t sz, bus_addr_t *addr)
|
2000-04-02 07:41:17 +00:00
|
|
|
{
|
|
|
|
u_int32_t blksz, start, idx, ofs, tmp, found;
|
|
|
|
struct emu_mem *mem = &sc->mem;
|
|
|
|
struct emu_memblk *blk;
|
|
|
|
void *buf;
|
|
|
|
|
|
|
|
blksz = sz / EMUPAGESIZE;
|
|
|
|
if (sz > (blksz * EMUPAGESIZE))
|
|
|
|
blksz++;
|
|
|
|
/* find a free block in the bitmap */
|
|
|
|
found = 0;
|
2000-08-06 18:10:05 +00:00
|
|
|
start = 1;
|
2004-01-11 10:30:56 +00:00
|
|
|
while (!found && start + blksz < EMUMAXPAGES) {
|
2000-04-02 07:41:17 +00:00
|
|
|
found = 1;
|
|
|
|
for (idx = start; idx < start + blksz; idx++)
|
|
|
|
if (mem->bmap[idx >> 3] & (1 << (idx & 7)))
|
|
|
|
found = 0;
|
|
|
|
if (!found)
|
|
|
|
start++;
|
|
|
|
}
|
|
|
|
if (!found)
|
|
|
|
return NULL;
|
|
|
|
blk = malloc(sizeof(*blk), M_DEVBUF, M_NOWAIT);
|
|
|
|
if (blk == NULL)
|
|
|
|
return NULL;
|
2003-02-20 17:31:12 +00:00
|
|
|
buf = emu_malloc(sc, sz, &blk->buf_addr);
|
|
|
|
*addr = blk->buf_addr;
|
2000-04-02 07:41:17 +00:00
|
|
|
if (buf == NULL) {
|
|
|
|
free(blk, M_DEVBUF);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
blk->buf = buf;
|
|
|
|
blk->pte_start = start;
|
|
|
|
blk->pte_size = blksz;
|
2004-01-11 10:30:56 +00:00
|
|
|
#ifdef EMUDEBUG
|
|
|
|
printf("buf %p, pte_start %d, pte_size %d\n", blk->buf,
|
|
|
|
blk->pte_start, blk->pte_size);
|
|
|
|
#endif
|
2000-04-02 07:41:17 +00:00
|
|
|
ofs = 0;
|
|
|
|
for (idx = start; idx < start + blksz; idx++) {
|
|
|
|
mem->bmap[idx >> 3] |= 1 << (idx & 7);
|
2003-02-26 16:11:18 +00:00
|
|
|
tmp = (u_int32_t)(u_long)((u_int8_t *)blk->buf_addr + ofs);
|
2004-01-11 10:30:56 +00:00
|
|
|
#ifdef EMUDEBUG
|
|
|
|
printf("pte[%d] -> %x phys, %x virt\n", idx, tmp,
|
|
|
|
((u_int32_t)buf) + ofs);
|
|
|
|
#endif
|
2000-04-18 19:11:38 +00:00
|
|
|
mem->ptb_pages[idx] = (tmp << 1) | idx;
|
2000-04-02 07:41:17 +00:00
|
|
|
ofs += EMUPAGESIZE;
|
|
|
|
}
|
|
|
|
SLIST_INSERT_HEAD(&mem->blocks, blk, link);
|
|
|
|
return buf;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
emu_memfree(struct sc_info *sc, void *buf)
|
|
|
|
{
|
|
|
|
u_int32_t idx, tmp;
|
|
|
|
struct emu_mem *mem = &sc->mem;
|
|
|
|
struct emu_memblk *blk, *i;
|
|
|
|
|
|
|
|
blk = NULL;
|
|
|
|
SLIST_FOREACH(i, &mem->blocks, link) {
|
|
|
|
if (i->buf == buf)
|
|
|
|
blk = i;
|
|
|
|
}
|
|
|
|
if (blk == NULL)
|
|
|
|
return EINVAL;
|
|
|
|
SLIST_REMOVE(&mem->blocks, blk, emu_memblk, link);
|
|
|
|
emu_free(sc, buf);
|
2003-02-20 17:31:12 +00:00
|
|
|
tmp = (u_int32_t)(sc->mem.silent_page_addr) << 1;
|
2000-04-02 07:41:17 +00:00
|
|
|
for (idx = blk->pte_start; idx < blk->pte_start + blk->pte_size; idx++) {
|
|
|
|
mem->bmap[idx >> 3] &= ~(1 << (idx & 7));
|
|
|
|
mem->ptb_pages[idx] = tmp | idx;
|
|
|
|
}
|
|
|
|
free(blk, M_DEVBUF);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
emu_memstart(struct sc_info *sc, void *buf)
|
|
|
|
{
|
|
|
|
struct emu_mem *mem = &sc->mem;
|
|
|
|
struct emu_memblk *blk, *i;
|
|
|
|
|
|
|
|
blk = NULL;
|
|
|
|
SLIST_FOREACH(i, &mem->blocks, link) {
|
|
|
|
if (i->buf == buf)
|
|
|
|
blk = i;
|
|
|
|
}
|
|
|
|
if (blk == NULL)
|
|
|
|
return -EINVAL;
|
|
|
|
return blk->pte_start;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2004-01-11 10:30:56 +00:00
|
|
|
emu_addefxop(struct sc_info *sc, int op, int z, int w, int x, int y,
|
|
|
|
u_int32_t *pc)
|
2000-04-02 07:41:17 +00:00
|
|
|
{
|
|
|
|
emu_wrefx(sc, (*pc) * 2, (x << 10) | y);
|
|
|
|
emu_wrefx(sc, (*pc) * 2 + 1, (op << 20) | (z << 10) | w);
|
|
|
|
(*pc)++;
|
|
|
|
}
|
|
|
|
|
2004-01-11 10:30:56 +00:00
|
|
|
static void
|
|
|
|
audigy_addefxop(struct sc_info *sc, int op, int z, int w, int x, int y,
|
|
|
|
u_int32_t *pc)
|
|
|
|
{
|
|
|
|
emu_wrefx(sc, (*pc) * 2, (x << 12) | y);
|
|
|
|
emu_wrefx(sc, (*pc) * 2 + 1, (op << 24) | (z << 12) | w);
|
|
|
|
(*pc)++;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
audigy_initefx(struct sc_info *sc)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
u_int32_t pc = 0;
|
|
|
|
|
|
|
|
/* skip 0, 0, -1, 0 - NOPs */
|
|
|
|
for (i = 0; i < 512; i++)
|
|
|
|
audigy_addefxop(sc, 0x0f, 0x0c0, 0x0c0, 0x0cf, 0x0c0, &pc);
|
|
|
|
|
|
|
|
for (i = 0; i < 512; i++)
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, 0, EMU_A_FXGPREGBASE + i, 0x0);
|
2004-01-11 10:30:56 +00:00
|
|
|
|
|
|
|
pc = 16;
|
|
|
|
|
|
|
|
/* stop fx processor */
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, 0, EMU_A_DBG, EMU_A_DBG_SINGLE_STEP);
|
2004-01-11 10:30:56 +00:00
|
|
|
|
|
|
|
/* Audigy 2 (EMU10K2) DSP Registers:
|
|
|
|
FX Bus
|
2006-01-21 15:23:15 +00:00
|
|
|
0x000-0x00f : 16 registers (?)
|
2004-01-11 10:30:56 +00:00
|
|
|
Input
|
|
|
|
0x040/0x041 : AC97 Codec (l/r)
|
|
|
|
0x042/0x043 : ADC, S/PDIF (l/r)
|
|
|
|
0x044/0x045 : Optical S/PDIF in (l/r)
|
2006-01-21 15:23:15 +00:00
|
|
|
0x046/0x047 : ?
|
2004-01-11 10:30:56 +00:00
|
|
|
0x048/0x049 : Line/Mic 2 (l/r)
|
|
|
|
0x04a/0x04b : RCA S/PDIF (l/r)
|
|
|
|
0x04c/0x04d : Aux 2 (l/r)
|
|
|
|
Output
|
|
|
|
0x060/0x061 : Digital Front (l/r)
|
|
|
|
0x062/0x063 : Digital Center/LFE
|
|
|
|
0x064/0x065 : AudigyDrive Heaphone (l/r)
|
|
|
|
0x066/0x067 : Digital Rear (l/r)
|
|
|
|
0x068/0x069 : Analog Front (l/r)
|
|
|
|
0x06a/0x06b : Analog Center/LFE
|
2006-01-21 15:23:15 +00:00
|
|
|
0x06c/0x06d : ?
|
2004-01-11 10:30:56 +00:00
|
|
|
0x06e/0x06f : Analog Rear (l/r)
|
|
|
|
0x070/0x071 : AC97 Output (l/r)
|
2006-01-21 15:23:15 +00:00
|
|
|
0x072/0x073 : ?
|
|
|
|
0x074/0x075 : ?
|
2004-01-11 10:30:56 +00:00
|
|
|
0x076/0x077 : ADC Recording Buffer (l/r)
|
|
|
|
Constants
|
|
|
|
0x0c0 - 0x0c4 = 0 - 4
|
|
|
|
0x0c5 = 0x8, 0x0c6 = 0x10, 0x0c7 = 0x20
|
|
|
|
0x0c8 = 0x100, 0x0c9 = 0x10000, 0x0ca = 0x80000
|
|
|
|
0x0cb = 0x10000000, 0x0cc = 0x20000000, 0x0cd = 0x40000000
|
|
|
|
0x0ce = 0x80000000, 0x0cf = 0x7fffffff, 0x0d0 = 0xffffffff
|
|
|
|
0x0d1 = 0xfffffffe, 0x0d2 = 0xc0000000, 0x0d3 = 0x41fbbcdc
|
2006-01-21 15:23:15 +00:00
|
|
|
0x0d4 = 0x5a7ef9db, 0x0d5 = 0x00100000, 0x0dc = 0x00000001 (?)
|
2004-01-11 10:30:56 +00:00
|
|
|
Temporary Values
|
2006-01-21 15:23:15 +00:00
|
|
|
0x0d6 : Accumulator (?)
|
2004-01-11 10:30:56 +00:00
|
|
|
0x0d7 : Condition Register
|
|
|
|
0x0d8 : Noise source
|
|
|
|
0x0d9 : Noise source
|
|
|
|
Tank Memory Data Registers
|
|
|
|
0x200 - 0x2ff
|
|
|
|
Tank Memory Address Registers
|
|
|
|
0x300 - 0x3ff
|
|
|
|
General Purpose Registers
|
|
|
|
0x400 - 0x5ff
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* AC97Output[l/r] = FXBus PCM[l/r] */
|
|
|
|
audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_AC97_L), A_C_00000000,
|
|
|
|
A_C_00000000, A_FXBUS(FXBUS_PCM_LEFT), &pc);
|
|
|
|
audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_AC97_R), A_C_00000000,
|
|
|
|
A_C_00000000, A_FXBUS(FXBUS_PCM_RIGHT), &pc);
|
|
|
|
|
|
|
|
/* GPR[0/1] = RCA S/PDIF[l/r] -- Master volume */
|
|
|
|
audigy_addefxop(sc, iACC3, A_GPR(0), A_C_00000000,
|
|
|
|
A_C_00000000, A_EXTIN(EXTIN_COAX_SPDIF_L), &pc);
|
|
|
|
audigy_addefxop(sc, iACC3, A_GPR(1), A_C_00000000,
|
|
|
|
A_C_00000000, A_EXTIN(EXTIN_COAX_SPDIF_R), &pc);
|
|
|
|
|
|
|
|
/* GPR[2] = GPR[0] (Left) / 2 + GPR[1] (Right) / 2 -- Central volume */
|
|
|
|
audigy_addefxop(sc, iINTERP, A_GPR(2), A_GPR(1),
|
|
|
|
A_C_40000000, A_GPR(0), &pc);
|
|
|
|
|
|
|
|
/* Headphones[l/r] = GPR[0/1] */
|
|
|
|
audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_HEADPHONE_L),
|
|
|
|
A_C_00000000, A_C_00000000, A_GPR(0), &pc);
|
|
|
|
audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_HEADPHONE_R),
|
|
|
|
A_C_00000000, A_C_00000000, A_GPR(1), &pc);
|
|
|
|
|
|
|
|
/* Analog Front[l/r] = GPR[0/1] */
|
|
|
|
audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_AFRONT_L), A_C_00000000,
|
|
|
|
A_C_00000000, A_GPR(0), &pc);
|
|
|
|
audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_AFRONT_R), A_C_00000000,
|
|
|
|
A_C_00000000, A_GPR(1), &pc);
|
|
|
|
|
|
|
|
/* Digital Front[l/r] = GPR[0/1] */
|
|
|
|
audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_FRONT_L), A_C_00000000,
|
|
|
|
A_C_00000000, A_GPR(0), &pc);
|
|
|
|
audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_FRONT_R), A_C_00000000,
|
|
|
|
A_C_00000000, A_GPR(1), &pc);
|
|
|
|
|
|
|
|
/* Center and Subwoofer configuration */
|
|
|
|
/* Analog Center = GPR[0] + GPR[2] */
|
|
|
|
audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_ACENTER), A_C_00000000,
|
|
|
|
A_GPR(0), A_GPR(2), &pc);
|
|
|
|
/* Analog Sub = GPR[1] + GPR[2] */
|
|
|
|
audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_ALFE), A_C_00000000,
|
|
|
|
A_GPR(1), A_GPR(2), &pc);
|
|
|
|
|
|
|
|
/* Digital Center = GPR[0] + GPR[2] */
|
|
|
|
audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_CENTER), A_C_00000000,
|
|
|
|
A_GPR(0), A_GPR(2), &pc);
|
|
|
|
/* Digital Sub = GPR[1] + GPR[2] */
|
|
|
|
audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_LFE), A_C_00000000,
|
|
|
|
A_GPR(1), A_GPR(2), &pc);
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
/* Analog Rear[l/r] = (GPR[0/1] * RearVolume[l/r]) >> 31 */
|
|
|
|
/* RearVolume = GPR[0x10/0x11] (Will this ever be implemented?) */
|
|
|
|
audigy_addefxop(sc, iMAC0, A_EXTOUT(A_EXTOUT_AREAR_L), A_C_00000000,
|
|
|
|
A_GPR(16), A_GPR(0), &pc);
|
|
|
|
audigy_addefxop(sc, iMAC0, A_EXTOUT(A_EXTOUT_AREAR_R), A_C_00000000,
|
|
|
|
A_GPR(17), A_GPR(1), &pc);
|
|
|
|
|
|
|
|
/* Digital Rear[l/r] = (GPR[0/1] * RearVolume[l/r]) >> 31 */
|
|
|
|
/* RearVolume = GPR[0x10/0x11] (Will this ever be implemented?) */
|
|
|
|
audigy_addefxop(sc, iMAC0, A_EXTOUT(A_EXTOUT_REAR_L), A_C_00000000,
|
|
|
|
A_GPR(16), A_GPR(0), &pc);
|
|
|
|
audigy_addefxop(sc, iMAC0, A_EXTOUT(A_EXTOUT_REAR_R), A_C_00000000,
|
|
|
|
A_GPR(17), A_GPR(1), &pc);
|
|
|
|
#else
|
|
|
|
/* XXX This is just a copy to the channel, since we do not have
|
|
|
|
* a patch manager, it is useful for have another output enabled.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Analog Rear[l/r] = GPR[0/1] */
|
|
|
|
audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_AREAR_L), A_C_00000000,
|
|
|
|
A_C_00000000, A_GPR(0), &pc);
|
|
|
|
audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_AREAR_R), A_C_00000000,
|
|
|
|
A_C_00000000, A_GPR(1), &pc);
|
|
|
|
|
|
|
|
/* Digital Rear[l/r] = GPR[0/1] */
|
|
|
|
audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_REAR_L), A_C_00000000,
|
|
|
|
A_C_00000000, A_GPR(0), &pc);
|
|
|
|
audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_REAR_R), A_C_00000000,
|
|
|
|
A_C_00000000, A_GPR(1), &pc);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* ADC Recording buffer[l/r] = AC97Input[l/r] */
|
|
|
|
audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_ADC_CAP_L), A_C_00000000,
|
|
|
|
A_C_00000000, A_EXTIN(A_EXTIN_AC97_L), &pc);
|
|
|
|
audigy_addefxop(sc, iACC3, A_EXTOUT(A_EXTOUT_ADC_CAP_R), A_C_00000000,
|
|
|
|
A_C_00000000, A_EXTIN(A_EXTIN_AC97_R), &pc);
|
|
|
|
|
|
|
|
/* resume normal operations */
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, 0, EMU_A_DBG, 0);
|
2004-01-11 10:30:56 +00:00
|
|
|
}
|
|
|
|
|
2000-04-02 07:41:17 +00:00
|
|
|
static void
|
|
|
|
emu_initefx(struct sc_info *sc)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
u_int32_t pc = 16;
|
|
|
|
|
2004-01-11 10:30:56 +00:00
|
|
|
/* acc3 0,0,0,0 - NOPs */
|
2000-04-02 07:41:17 +00:00
|
|
|
for (i = 0; i < 512; i++) {
|
|
|
|
emu_wrefx(sc, i * 2, 0x10040);
|
|
|
|
emu_wrefx(sc, i * 2 + 1, 0x610040);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < 256; i++)
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, 0, EMU_FXGPREGBASE + i, 0);
|
2000-04-02 07:41:17 +00:00
|
|
|
|
|
|
|
/* FX-8010 DSP Registers:
|
|
|
|
FX Bus
|
|
|
|
0x000-0x00f : 16 registers
|
|
|
|
Input
|
|
|
|
0x010/0x011 : AC97 Codec (l/r)
|
|
|
|
0x012/0x013 : ADC, S/PDIF (l/r)
|
|
|
|
0x014/0x015 : Mic(left), Zoom (l/r)
|
2004-01-11 10:30:56 +00:00
|
|
|
0x016/0x017 : TOS link in (l/r)
|
|
|
|
0x018/0x019 : Line/Mic 1 (l/r)
|
|
|
|
0x01a/0x01b : COAX S/PDIF (l/r)
|
|
|
|
0x01c/0x01d : Line/Mic 2 (l/r)
|
2000-04-02 07:41:17 +00:00
|
|
|
Output
|
|
|
|
0x020/0x021 : AC97 Output (l/r)
|
|
|
|
0x022/0x023 : TOS link out (l/r)
|
2004-01-11 10:30:56 +00:00
|
|
|
0x024/0x025 : Center/LFE
|
2000-04-02 07:41:17 +00:00
|
|
|
0x026/0x027 : LiveDrive Headphone (l/r)
|
|
|
|
0x028/0x029 : Rear Channel (l/r)
|
|
|
|
0x02a/0x02b : ADC Recording Buffer (l/r)
|
2004-01-11 10:30:56 +00:00
|
|
|
0x02c : Mic Recording Buffer
|
|
|
|
0x031/0x032 : Analog Center/LFE
|
2000-04-02 07:41:17 +00:00
|
|
|
Constants
|
|
|
|
0x040 - 0x044 = 0 - 4
|
|
|
|
0x045 = 0x8, 0x046 = 0x10, 0x047 = 0x20
|
|
|
|
0x048 = 0x100, 0x049 = 0x10000, 0x04a = 0x80000
|
|
|
|
0x04b = 0x10000000, 0x04c = 0x20000000, 0x04d = 0x40000000
|
2004-01-11 10:30:56 +00:00
|
|
|
0x04e = 0x80000000, 0x04f = 0x7fffffff, 0x050 = 0xffffffff
|
|
|
|
0x051 = 0xfffffffe, 0x052 = 0xc0000000, 0x053 = 0x41fbbcdc
|
|
|
|
0x054 = 0x5a7ef9db, 0x055 = 0x00100000
|
2000-04-02 07:41:17 +00:00
|
|
|
Temporary Values
|
|
|
|
0x056 : Accumulator
|
2004-01-11 10:30:56 +00:00
|
|
|
0x057 : Condition Register
|
|
|
|
0x058 : Noise source
|
|
|
|
0x059 : Noise source
|
|
|
|
0x05a : IRQ Register
|
|
|
|
0x05b : TRAM Delay Base Address Count
|
2000-04-02 07:41:17 +00:00
|
|
|
General Purpose Registers
|
|
|
|
0x100 - 0x1ff
|
|
|
|
Tank Memory Data Registers
|
|
|
|
0x200 - 0x2ff
|
|
|
|
Tank Memory Address Registers
|
|
|
|
0x300 - 0x3ff
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Routing - this will be configurable in later version */
|
|
|
|
|
|
|
|
/* GPR[0/1] = FX * 4 + SPDIF-in */
|
2004-01-11 10:30:56 +00:00
|
|
|
emu_addefxop(sc, iMACINT0, GPR(0), EXTIN(EXTIN_SPDIF_CD_L),
|
|
|
|
FXBUS(FXBUS_PCM_LEFT), C_00000004, &pc);
|
|
|
|
emu_addefxop(sc, iMACINT0, GPR(1), EXTIN(EXTIN_SPDIF_CD_R),
|
|
|
|
FXBUS(FXBUS_PCM_RIGHT), C_00000004, &pc);
|
|
|
|
|
2000-04-02 07:41:17 +00:00
|
|
|
/* GPR[0/1] += APS-input */
|
2004-01-11 10:30:56 +00:00
|
|
|
emu_addefxop(sc, iACC3, GPR(0), GPR(0), C_00000000,
|
|
|
|
sc->APS ? EXTIN(EXTIN_TOSLINK_L) : C_00000000, &pc);
|
|
|
|
emu_addefxop(sc, iACC3, GPR(1), GPR(1), C_00000000,
|
|
|
|
sc->APS ? EXTIN(EXTIN_TOSLINK_R) : C_00000000, &pc);
|
|
|
|
|
2000-04-02 07:41:17 +00:00
|
|
|
/* FrontOut (AC97) = GPR[0/1] */
|
2004-01-11 10:30:56 +00:00
|
|
|
emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_AC97_L), C_00000000,
|
|
|
|
C_00000000, GPR(0), &pc);
|
|
|
|
emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_AC97_R), C_00000000,
|
|
|
|
C_00000001, GPR(1), &pc);
|
|
|
|
|
|
|
|
/* GPR[2] = GPR[0] (Left) / 2 + GPR[1] (Right) / 2 -- Central volume */
|
|
|
|
emu_addefxop(sc, iINTERP, GPR(2), GPR(1), C_40000000, GPR(0), &pc);
|
|
|
|
|
|
|
|
#if 0
|
2000-04-02 07:41:17 +00:00
|
|
|
/* RearOut = (GPR[0/1] * RearVolume) >> 31 */
|
2004-01-11 10:30:56 +00:00
|
|
|
/* RearVolume = GPR[0x10/0x11] */
|
|
|
|
emu_addefxop(sc, iMAC0, EXTOUT(EXTOUT_REAR_L), C_00000000,
|
|
|
|
GPR(16), GPR(0), &pc);
|
|
|
|
emu_addefxop(sc, iMAC0, EXTOUT(EXTOUT_REAR_R), C_00000000,
|
|
|
|
GPR(17), GPR(1), &pc);
|
|
|
|
#else
|
|
|
|
/* XXX This is just a copy to the channel, since we do not have
|
|
|
|
* a patch manager, it is useful for have another output enabled.
|
|
|
|
*/
|
2000-04-02 07:41:17 +00:00
|
|
|
|
2004-01-11 10:30:56 +00:00
|
|
|
/* Rear[l/r] = GPR[0/1] */
|
|
|
|
emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_REAR_L), C_00000000,
|
|
|
|
C_00000000, GPR(0), &pc);
|
|
|
|
emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_REAR_R), C_00000000,
|
|
|
|
C_00000000, GPR(1), &pc);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* TOS out[l/r] = GPR[0/1] */
|
|
|
|
emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_TOSLINK_L), C_00000000,
|
|
|
|
C_00000000, GPR(0), &pc);
|
|
|
|
emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_TOSLINK_R), C_00000000,
|
|
|
|
C_00000000, GPR(1), &pc);
|
|
|
|
|
|
|
|
/* Center and Subwoofer configuration */
|
|
|
|
/* Analog Center = GPR[0] + GPR[2] */
|
|
|
|
emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_ACENTER), C_00000000,
|
|
|
|
GPR(0), GPR(2), &pc);
|
|
|
|
/* Analog Sub = GPR[1] + GPR[2] */
|
|
|
|
emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_ALFE), C_00000000,
|
|
|
|
GPR(1), GPR(2), &pc);
|
|
|
|
/* Digital Center = GPR[0] + GPR[2] */
|
2006-07-15 19:19:54 +00:00
|
|
|
emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_AC97_CENTER), C_00000000,
|
2004-01-11 10:30:56 +00:00
|
|
|
GPR(0), GPR(2), &pc);
|
|
|
|
/* Digital Sub = GPR[1] + GPR[2] */
|
2006-07-15 19:19:54 +00:00
|
|
|
emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_AC97_LFE), C_00000000,
|
2004-01-11 10:30:56 +00:00
|
|
|
GPR(1), GPR(2), &pc);
|
|
|
|
|
|
|
|
/* Headphones[l/r] = GPR[0/1] */
|
|
|
|
emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_HEADPHONE_L), C_00000000,
|
|
|
|
C_00000000, GPR(0), &pc);
|
|
|
|
emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_HEADPHONE_R), C_00000000,
|
|
|
|
C_00000000, GPR(1), &pc);
|
|
|
|
|
|
|
|
/* ADC Recording buffer[l/r] = AC97Input[l/r] */
|
|
|
|
emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_ADC_CAP_L), C_00000000,
|
|
|
|
C_00000000, EXTIN(EXTIN_AC97_L), &pc);
|
|
|
|
emu_addefxop(sc, iACC3, EXTOUT(EXTOUT_ADC_CAP_R), C_00000000,
|
|
|
|
C_00000000, EXTIN(EXTIN_AC97_R), &pc);
|
|
|
|
|
|
|
|
/* resume normal operations */
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, 0, EMU_DBG, 0);
|
2000-04-02 07:41:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Probe and attach the card */
|
|
|
|
static int
|
|
|
|
emu_init(struct sc_info *sc)
|
|
|
|
{
|
|
|
|
u_int32_t spcs, ch, tmp, i;
|
|
|
|
|
2004-01-11 10:30:56 +00:00
|
|
|
if (sc->audigy) {
|
|
|
|
/* enable additional AC97 slots */
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, 0, EMU_AC97SLOT, EMU_AC97SLOT_CENTER | EMU_AC97SLOT_LFE);
|
2004-01-11 10:30:56 +00:00
|
|
|
}
|
|
|
|
|
2003-04-20 07:43:09 +00:00
|
|
|
/* disable audio and lock cache */
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wr(sc, EMU_HCFG,
|
|
|
|
EMU_HCFG_LOCKSOUNDCACHE | EMU_HCFG_LOCKTANKCACHE_MASK | EMU_HCFG_MUTEBUTTONENABLE,
|
2004-01-11 10:30:56 +00:00
|
|
|
4);
|
2000-04-02 07:41:17 +00:00
|
|
|
|
|
|
|
/* reset recording buffers */
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, 0, EMU_MICBS, EMU_RECBS_BUFSIZE_NONE);
|
|
|
|
emu_wrptr(sc, 0, EMU_MICBA, 0);
|
|
|
|
emu_wrptr(sc, 0, EMU_FXBS, EMU_RECBS_BUFSIZE_NONE);
|
|
|
|
emu_wrptr(sc, 0, EMU_FXBA, 0);
|
|
|
|
emu_wrptr(sc, 0, EMU_ADCBS, EMU_RECBS_BUFSIZE_NONE);
|
|
|
|
emu_wrptr(sc, 0, EMU_ADCBA, 0);
|
2000-04-02 07:41:17 +00:00
|
|
|
|
|
|
|
/* disable channel interrupt */
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wr(sc, EMU_INTE,
|
|
|
|
EMU_INTE_INTERTIMERENB | EMU_INTE_SAMPLERATER | EMU_INTE_PCIERRENABLE,
|
2004-01-11 10:30:56 +00:00
|
|
|
4);
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, 0, EMU_CLIEL, 0);
|
|
|
|
emu_wrptr(sc, 0, EMU_CLIEH, 0);
|
|
|
|
emu_wrptr(sc, 0, EMU_SOLEL, 0);
|
|
|
|
emu_wrptr(sc, 0, EMU_SOLEH, 0);
|
2000-04-02 07:41:17 +00:00
|
|
|
|
2004-01-11 10:30:56 +00:00
|
|
|
/* wonder what these do... */
|
|
|
|
if (sc->audigy) {
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, 0, EMU_SPBYPASS, 0xf00);
|
|
|
|
emu_wrptr(sc, 0, EMU_AC97SLOT, 0x3);
|
2004-01-11 10:30:56 +00:00
|
|
|
}
|
|
|
|
|
2000-04-02 07:41:17 +00:00
|
|
|
/* init envelope engine */
|
|
|
|
for (ch = 0; ch < NUM_G; ch++) {
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_DCYSUSV, ENV_OFF);
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_IP, 0);
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_VTFT, 0xffff);
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_CVCF, 0xffff);
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_PTRX, 0);
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_CPF, 0);
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_CCR, 0);
|
|
|
|
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_PSST, 0);
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_DSL, 0x10);
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_CCCA, 0);
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_Z1, 0);
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_Z2, 0);
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_FXRT, 0xd01c0000);
|
|
|
|
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_ATKHLDM, 0);
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_DCYSUSM, 0);
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_IFATN, 0xffff);
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_PEFE, 0);
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_FMMOD, 0);
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_TREMFRQ, 24); /* 1 Hz */
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_FM2FRQ2, 24); /* 1 Hz */
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_TEMPENV, 0);
|
2000-04-02 07:41:17 +00:00
|
|
|
|
|
|
|
/*** these are last so OFF prevents writing ***/
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_LFOVAL2, 0);
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_LFOVAL1, 0);
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_ATKHLDV, 0);
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_ENVVOL, 0);
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_ENVVAL, 0);
|
2000-04-02 07:41:17 +00:00
|
|
|
|
2004-01-11 10:30:56 +00:00
|
|
|
if (sc->audigy) {
|
|
|
|
/* audigy cards need this to initialize correctly */
|
|
|
|
emu_wrptr(sc, ch, 0x4c, 0);
|
|
|
|
emu_wrptr(sc, ch, 0x4d, 0);
|
|
|
|
emu_wrptr(sc, ch, 0x4e, 0);
|
|
|
|
emu_wrptr(sc, ch, 0x4f, 0);
|
|
|
|
/* set default routing */
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, ch, EMU_A_CHAN_FXRT1, 0x03020100);
|
|
|
|
emu_wrptr(sc, ch, EMU_A_CHAN_FXRT2, 0x3f3f3f3f);
|
|
|
|
emu_wrptr(sc, ch, EMU_A_CHAN_SENDAMOUNTS, 0);
|
2004-01-11 10:30:56 +00:00
|
|
|
}
|
|
|
|
|
2000-04-02 07:41:17 +00:00
|
|
|
sc->voice[ch].vnum = ch;
|
|
|
|
sc->voice[ch].slave = NULL;
|
|
|
|
sc->voice[ch].busy = 0;
|
2000-06-13 23:24:40 +00:00
|
|
|
sc->voice[ch].ismaster = 0;
|
2000-08-06 18:10:05 +00:00
|
|
|
sc->voice[ch].running = 0;
|
2000-04-02 07:41:17 +00:00
|
|
|
sc->voice[ch].b16 = 0;
|
|
|
|
sc->voice[ch].stereo = 0;
|
|
|
|
sc->voice[ch].speed = 0;
|
|
|
|
sc->voice[ch].start = 0;
|
|
|
|
sc->voice[ch].end = 0;
|
|
|
|
sc->voice[ch].channel = NULL;
|
2003-04-20 08:37:29 +00:00
|
|
|
}
|
|
|
|
sc->pnum = sc->rnum = 0;
|
2000-04-02 07:41:17 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Init to 0x02109204 :
|
|
|
|
* Clock accuracy = 0 (1000ppm)
|
|
|
|
* Sample Rate = 2 (48kHz)
|
|
|
|
* Audio Channel = 1 (Left of 2)
|
|
|
|
* Source Number = 0 (Unspecified)
|
|
|
|
* Generation Status = 1 (Original for Cat Code 12)
|
|
|
|
* Cat Code = 12 (Digital Signal Mixer)
|
|
|
|
* Mode = 0 (Mode 0)
|
|
|
|
* Emphasis = 0 (None)
|
|
|
|
* CP = 1 (Copyright unasserted)
|
|
|
|
* AN = 0 (Audio data)
|
|
|
|
* P = 0 (Consumer)
|
|
|
|
*/
|
2012-01-03 21:04:54 +00:00
|
|
|
spcs = EMU_SPCS_CLKACCY_1000PPM | EMU_SPCS_SAMPLERATE_48 |
|
|
|
|
EMU_SPCS_CHANNELNUM_LEFT | EMU_SPCS_SOURCENUM_UNSPEC |
|
|
|
|
EMU_SPCS_GENERATIONSTATUS | 0x00001200 | 0x00000000 |
|
|
|
|
EMU_SPCS_EMPHASIS_NONE | EMU_SPCS_COPYRIGHT;
|
|
|
|
emu_wrptr(sc, 0, EMU_SPCS0, spcs);
|
|
|
|
emu_wrptr(sc, 0, EMU_SPCS1, spcs);
|
|
|
|
emu_wrptr(sc, 0, EMU_SPCS2, spcs);
|
2000-04-02 07:41:17 +00:00
|
|
|
|
2004-01-11 10:30:56 +00:00
|
|
|
if (!sc->audigy)
|
|
|
|
emu_initefx(sc);
|
|
|
|
else if (sc->audigy2) { /* Audigy 2 */
|
|
|
|
/* from ALSA initialization code: */
|
|
|
|
|
|
|
|
/* Hack for Alice3 to work independent of haP16V driver */
|
|
|
|
u_int32_t tmp;
|
|
|
|
|
|
|
|
/* Setup SRCMulti_I2S SamplingRate */
|
2012-01-03 21:04:54 +00:00
|
|
|
tmp = emu_rdptr(sc, 0, EMU_A_SPDIF_SAMPLERATE) & 0xfffff1ff;
|
|
|
|
emu_wrptr(sc, 0, EMU_A_SPDIF_SAMPLERATE, tmp | 0x400);
|
2004-01-11 10:30:56 +00:00
|
|
|
|
|
|
|
/* Setup SRCSel (Enable SPDIF, I2S SRCMulti) */
|
|
|
|
emu_wr(sc, 0x20, 0x00600000, 4);
|
|
|
|
emu_wr(sc, 0x24, 0x00000014, 4);
|
|
|
|
|
|
|
|
/* Setup SRCMulti Input Audio Enable */
|
|
|
|
emu_wr(sc, 0x20, 0x006e0000, 4);
|
|
|
|
emu_wr(sc, 0x24, 0xff00ff00, 4);
|
|
|
|
}
|
2000-04-02 07:41:17 +00:00
|
|
|
|
2000-04-04 02:16:15 +00:00
|
|
|
SLIST_INIT(&sc->mem.blocks);
|
2004-01-11 10:30:56 +00:00
|
|
|
sc->mem.ptb_pages = emu_malloc(sc, EMUMAXPAGES * sizeof(u_int32_t),
|
|
|
|
&sc->mem.ptb_pages_addr);
|
2000-04-04 02:16:15 +00:00
|
|
|
if (sc->mem.ptb_pages == NULL)
|
|
|
|
return -1;
|
|
|
|
|
2004-01-11 10:30:56 +00:00
|
|
|
sc->mem.silent_page = emu_malloc(sc, EMUPAGESIZE,
|
|
|
|
&sc->mem.silent_page_addr);
|
2000-04-04 02:16:15 +00:00
|
|
|
if (sc->mem.silent_page == NULL) {
|
|
|
|
emu_free(sc, sc->mem.ptb_pages);
|
2000-04-02 07:41:17 +00:00
|
|
|
return -1;
|
2000-04-04 02:16:15 +00:00
|
|
|
}
|
2000-04-02 07:41:17 +00:00
|
|
|
/* Clear page with silence & setup all pointers to this page */
|
|
|
|
bzero(sc->mem.silent_page, EMUPAGESIZE);
|
2003-02-20 17:31:12 +00:00
|
|
|
tmp = (u_int32_t)(sc->mem.silent_page_addr) << 1;
|
2004-01-11 10:30:56 +00:00
|
|
|
for (i = 0; i < EMUMAXPAGES; i++)
|
2000-04-18 19:11:38 +00:00
|
|
|
sc->mem.ptb_pages[i] = tmp | i;
|
2000-04-04 02:16:15 +00:00
|
|
|
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, 0, EMU_PTB, (sc->mem.ptb_pages_addr));
|
|
|
|
emu_wrptr(sc, 0, EMU_TCB, 0); /* taken from original driver */
|
|
|
|
emu_wrptr(sc, 0, EMU_TCBS, 0); /* taken from original driver */
|
2000-04-02 07:41:17 +00:00
|
|
|
|
|
|
|
for (ch = 0; ch < NUM_G; ch++) {
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_MAPA, tmp | EMU_CHAN_MAP_PTI_MASK);
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_MAPB, tmp | EMU_CHAN_MAP_PTI_MASK);
|
2000-04-02 07:41:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* emu_memalloc(sc, EMUPAGESIZE); */
|
|
|
|
/*
|
|
|
|
* Hokay, now enable the AUD bit
|
2004-01-11 10:30:56 +00:00
|
|
|
*
|
|
|
|
* Audigy
|
|
|
|
* Enable Audio = 0 (enabled after fx processor initialization)
|
|
|
|
* Mute Disable Audio = 0
|
|
|
|
* Joystick = 1
|
|
|
|
*
|
|
|
|
* Audigy 2
|
|
|
|
* Enable Audio = 1
|
|
|
|
* Mute Disable Audio = 0
|
|
|
|
* Joystick = 1
|
|
|
|
* GP S/PDIF AC3 Enable = 1
|
|
|
|
* CD S/PDIF AC3 Enable = 1
|
|
|
|
*
|
|
|
|
* EMU10K1
|
2000-04-02 07:41:17 +00:00
|
|
|
* Enable Audio = 1
|
|
|
|
* Mute Disable Audio = 0
|
|
|
|
* Lock Tank Memory = 1
|
|
|
|
* Lock Sound Memory = 0
|
|
|
|
* Auto Mute = 1
|
|
|
|
*/
|
2004-01-11 10:30:56 +00:00
|
|
|
|
|
|
|
if (sc->audigy) {
|
2012-01-03 21:04:54 +00:00
|
|
|
tmp = EMU_HCFG_AUTOMUTE | EMU_HCFG_JOYENABLE;
|
2004-01-11 10:30:56 +00:00
|
|
|
if (sc->audigy2) /* Audigy 2 */
|
2012-01-03 21:04:54 +00:00
|
|
|
tmp = EMU_HCFG_AUDIOENABLE | EMU_HCFG_AC3ENABLE_CDSPDIF |
|
|
|
|
EMU_HCFG_AC3ENABLE_GPSPDIF;
|
|
|
|
emu_wr(sc, EMU_HCFG, tmp, 4);
|
2004-01-11 10:30:56 +00:00
|
|
|
|
|
|
|
audigy_initefx(sc);
|
|
|
|
|
|
|
|
/* from ALSA initialization code: */
|
|
|
|
|
|
|
|
/* enable audio and disable both audio/digital outputs */
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wr(sc, EMU_HCFG, emu_rd(sc, EMU_HCFG, 4) | EMU_HCFG_AUDIOENABLE, 4);
|
|
|
|
emu_wr(sc, EMU_A_IOCFG, emu_rd(sc, EMU_A_IOCFG, 4) & ~EMU_A_IOCFG_GPOUT_AD,
|
2004-01-11 10:30:56 +00:00
|
|
|
4);
|
|
|
|
if (sc->audigy2) { /* Audigy 2 */
|
|
|
|
/* Unmute Analog.
|
|
|
|
* Set GPO6 to 1 for Apollo. This has to be done after
|
|
|
|
* init Alice3 I2SOut beyond 48kHz.
|
|
|
|
* So, sequence is important.
|
|
|
|
*/
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wr(sc, EMU_A_IOCFG,
|
|
|
|
emu_rd(sc, EMU_A_IOCFG, 4) | EMU_A_IOCFG_GPOUT_A, 4);
|
2004-01-11 10:30:56 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* EMU10K1 initialization code */
|
2012-01-03 21:04:54 +00:00
|
|
|
tmp = EMU_HCFG_AUDIOENABLE | EMU_HCFG_LOCKTANKCACHE_MASK
|
|
|
|
| EMU_HCFG_AUTOMUTE;
|
2004-01-11 10:30:56 +00:00
|
|
|
if (sc->rev >= 6)
|
2012-01-03 21:04:54 +00:00
|
|
|
tmp |= EMU_HCFG_JOYENABLE;
|
2004-01-11 10:30:56 +00:00
|
|
|
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wr(sc, EMU_HCFG, tmp, 4);
|
2004-01-11 10:30:56 +00:00
|
|
|
|
|
|
|
/* TOSLink detection */
|
|
|
|
sc->tos_link = 0;
|
2012-01-03 21:04:54 +00:00
|
|
|
tmp = emu_rd(sc, EMU_HCFG, 4);
|
|
|
|
if (tmp & (EMU_HCFG_GPINPUT0 | EMU_HCFG_GPINPUT1)) {
|
|
|
|
emu_wr(sc, EMU_HCFG, tmp | EMU_HCFG_GPOUT1, 4);
|
2004-01-11 10:30:56 +00:00
|
|
|
DELAY(50);
|
2012-01-03 21:04:54 +00:00
|
|
|
if (tmp != (emu_rd(sc, EMU_HCFG, 4) & ~EMU_HCFG_GPOUT1)) {
|
2004-01-11 10:30:56 +00:00
|
|
|
sc->tos_link = 1;
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wr(sc, EMU_HCFG, tmp, 4);
|
2004-01-11 10:30:56 +00:00
|
|
|
}
|
2000-04-02 07:41:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2000-09-05 21:06:11 +00:00
|
|
|
static int
|
|
|
|
emu_uninit(struct sc_info *sc)
|
|
|
|
{
|
|
|
|
u_int32_t ch;
|
|
|
|
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wr(sc, EMU_INTE, 0, 4);
|
2000-09-05 21:06:11 +00:00
|
|
|
for (ch = 0; ch < NUM_G; ch++)
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_DCYSUSV, ENV_OFF);
|
2000-09-05 21:06:11 +00:00
|
|
|
for (ch = 0; ch < NUM_G; ch++) {
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_VTFT, 0);
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_CVCF, 0);
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_PTRX, 0);
|
|
|
|
emu_wrptr(sc, ch, EMU_CHAN_CPF, 0);
|
2003-04-20 08:37:29 +00:00
|
|
|
}
|
2000-09-05 21:06:11 +00:00
|
|
|
|
2004-01-11 10:30:56 +00:00
|
|
|
if (sc->audigy) { /* stop fx processor */
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, 0, EMU_A_DBG, EMU_A_DBG_SINGLE_STEP);
|
2004-01-11 10:30:56 +00:00
|
|
|
}
|
|
|
|
|
2003-04-20 07:43:09 +00:00
|
|
|
/* disable audio and lock cache */
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wr(sc, EMU_HCFG,
|
|
|
|
EMU_HCFG_LOCKSOUNDCACHE | EMU_HCFG_LOCKTANKCACHE_MASK | EMU_HCFG_MUTEBUTTONENABLE,
|
2004-01-11 10:30:56 +00:00
|
|
|
4);
|
2000-09-05 21:06:11 +00:00
|
|
|
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, 0, EMU_PTB, 0);
|
2000-09-05 21:06:11 +00:00
|
|
|
/* reset recording buffers */
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, 0, EMU_MICBS, EMU_RECBS_BUFSIZE_NONE);
|
|
|
|
emu_wrptr(sc, 0, EMU_MICBA, 0);
|
|
|
|
emu_wrptr(sc, 0, EMU_FXBS, EMU_RECBS_BUFSIZE_NONE);
|
|
|
|
emu_wrptr(sc, 0, EMU_FXBA, 0);
|
|
|
|
emu_wrptr(sc, 0, EMU_FXWC, 0);
|
|
|
|
emu_wrptr(sc, 0, EMU_ADCBS, EMU_RECBS_BUFSIZE_NONE);
|
|
|
|
emu_wrptr(sc, 0, EMU_ADCBA, 0);
|
|
|
|
emu_wrptr(sc, 0, EMU_TCB, 0);
|
|
|
|
emu_wrptr(sc, 0, EMU_TCBS, 0);
|
2000-09-05 21:06:11 +00:00
|
|
|
|
|
|
|
/* disable channel interrupt */
|
2012-01-03 21:04:54 +00:00
|
|
|
emu_wrptr(sc, 0, EMU_CLIEL, 0);
|
|
|
|
emu_wrptr(sc, 0, EMU_CLIEH, 0);
|
|
|
|
emu_wrptr(sc, 0, EMU_SOLEL, 0);
|
|
|
|
emu_wrptr(sc, 0, EMU_SOLEH, 0);
|
2000-09-05 21:06:11 +00:00
|
|
|
|
|
|
|
/* init envelope engine */
|
|
|
|
if (!SLIST_EMPTY(&sc->mem.blocks))
|
|
|
|
device_printf(sc->dev, "warning: memblock list not empty\n");
|
|
|
|
emu_free(sc, sc->mem.ptb_pages);
|
|
|
|
emu_free(sc, sc->mem.silent_page);
|
|
|
|
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
if(sc->mpu)
|
|
|
|
mpu401_uninit(sc->mpu);
|
2000-09-05 21:06:11 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2000-04-02 07:41:17 +00:00
|
|
|
static int
|
|
|
|
emu_pci_probe(device_t dev)
|
|
|
|
{
|
|
|
|
char *s = NULL;
|
|
|
|
|
|
|
|
switch (pci_get_devid(dev)) {
|
|
|
|
case EMU10K1_PCI_ID:
|
|
|
|
s = "Creative EMU10K1";
|
|
|
|
break;
|
2004-01-11 10:30:56 +00:00
|
|
|
|
2001-10-08 06:10:39 +00:00
|
|
|
case EMU10K2_PCI_ID:
|
2004-01-11 10:30:56 +00:00
|
|
|
if (pci_get_revid(dev) == 0x04)
|
|
|
|
s = "Creative Audigy 2 (EMU10K2)";
|
|
|
|
else
|
|
|
|
s = "Creative Audigy (EMU10K2)";
|
2001-10-08 06:10:39 +00:00
|
|
|
break;
|
2004-01-11 10:30:56 +00:00
|
|
|
|
2005-03-01 08:58:06 +00:00
|
|
|
case EMU10K3_PCI_ID:
|
|
|
|
s = "Creative Audigy 2 (EMU10K3)";
|
|
|
|
break;
|
|
|
|
|
2001-10-08 06:10:39 +00:00
|
|
|
default:
|
|
|
|
return ENXIO;
|
2000-04-02 07:41:17 +00:00
|
|
|
}
|
|
|
|
|
2001-10-08 06:10:39 +00:00
|
|
|
device_set_desc(dev, s);
|
2006-08-07 23:00:36 +00:00
|
|
|
return BUS_PROBE_LOW_PRIORITY;
|
2000-04-02 07:41:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
emu_pci_attach(device_t dev)
|
|
|
|
{
|
2000-09-09 19:21:04 +00:00
|
|
|
struct ac97_info *codec = NULL;
|
2001-10-08 06:10:39 +00:00
|
|
|
struct sc_info *sc;
|
|
|
|
int i, gotmic;
|
|
|
|
char status[SND_STATUSLEN];
|
2000-04-02 07:41:17 +00:00
|
|
|
|
2007-06-17 06:10:43 +00:00
|
|
|
sc = malloc(sizeof(*sc), M_DEVBUF, M_WAITOK | M_ZERO);
|
Fix severe out-of-bound mtx "type" pointer, causing WITNESS refcount
confusions and panic provided that the following conditions are met:
1) WITNESS is enabled (watch/trace).
2) Using modules, instead of statically linked (Not a strict
requirement, but easier to reproduce this way).
3) 2 or more modules share the same mtx type ("sound softc").
- They might share the same name (strcmp() == 0), but it always
point to different address.
4) Repetitive kldunload/load on any module that shares the same mtx
type (Not a strict requirement, but easier to reproduce this way).
Consider module A and module B:
- From enroll() - subr_witness.c:
* Load module A. Everything seems fine right now.
wA-w_refcount == 1 ; wA-w_name = "sound softc"
* Load module B.
* w->w_name == description will always fail.
("sound softc" from A and B point to different address).
* wA->w_refcount > 0 && strcmp(description, wA->w_name) == 0
* enroll() will return wA instead of returning (possibly unique)
wB.
wA->w_refcount++ , == 2.
* Unload module A, mtx_destroy(), wA->w_name become invalid,
but wA->w_refcount-- become 1 instead of 0. wA will not be
removed from witness list.
* Some other places call mtx_init(), iterating witness list,
found wA, failed on wA->w_name == description
* wA->w_refcount > 0 && strcmp(description, wA->w_name)
* Panic on strcmp() since wA->w_name no longer point to valid
address.
Note that this could happened in other places as well, not just sound
(eg. consider lots of drivers that share simmilar MTX_NETWORK_LOCK).
Solutions (for sound case):
1) Provide unique mtx type string for each mutex creation (chosen)
or
2) Put "sound softc" global variable somewhere and use it.
2007-03-15 16:41:27 +00:00
|
|
|
sc->lock = snd_mtxcreate(device_get_nameunit(dev), "snd_emu10k1 softc");
|
2000-06-13 23:24:40 +00:00
|
|
|
sc->dev = dev;
|
2000-04-02 07:41:17 +00:00
|
|
|
sc->type = pci_get_devid(dev);
|
|
|
|
sc->rev = pci_get_revid(dev);
|
2005-03-01 08:58:06 +00:00
|
|
|
sc->audigy = sc->type == EMU10K2_PCI_ID || sc->type == EMU10K3_PCI_ID;
|
2004-01-11 10:30:56 +00:00
|
|
|
sc->audigy2 = (sc->audigy && sc->rev == 0x04);
|
|
|
|
sc->nchans = sc->audigy ? 8 : 4;
|
2012-01-03 21:04:54 +00:00
|
|
|
sc->addrmask = sc->audigy ? EMU_A_PTR_ADDR_MASK : EMU_PTR_ADDR_MASK;
|
2000-04-02 07:41:17 +00:00
|
|
|
|
2013-08-12 23:30:01 +00:00
|
|
|
pci_enable_busmaster(dev);
|
2000-04-02 07:41:17 +00:00
|
|
|
|
2003-09-02 17:30:40 +00:00
|
|
|
i = PCIR_BAR(0);
|
2004-03-17 17:50:55 +00:00
|
|
|
sc->reg = bus_alloc_resource_any(dev, SYS_RES_IOPORT, &i, RF_ACTIVE);
|
2001-10-08 06:10:39 +00:00
|
|
|
if (sc->reg == NULL) {
|
2000-04-02 07:41:17 +00:00
|
|
|
device_printf(dev, "unable to map register space\n");
|
|
|
|
goto bad;
|
|
|
|
}
|
2001-10-08 06:10:39 +00:00
|
|
|
sc->st = rman_get_bustag(sc->reg);
|
|
|
|
sc->sh = rman_get_bushandle(sc->reg);
|
|
|
|
|
|
|
|
sc->bufsz = pcm_getbuffersize(dev, 4096, EMU_DEFAULT_BUFSZ, 65536);
|
2000-04-02 07:41:17 +00:00
|
|
|
|
2007-02-23 13:47:34 +00:00
|
|
|
if (bus_dma_tag_create(/*parent*/bus_get_dma_tag(dev), /*alignment*/2,
|
|
|
|
/*boundary*/0,
|
2011-02-09 11:28:57 +00:00
|
|
|
/*lowaddr*/(1U << 31) - 1, /* can only access 0-2gb */
|
2000-04-02 07:41:17 +00:00
|
|
|
/*highaddr*/BUS_SPACE_MAXADDR,
|
|
|
|
/*filter*/NULL, /*filterarg*/NULL,
|
2001-10-08 06:10:39 +00:00
|
|
|
/*maxsize*/sc->bufsz, /*nsegments*/1, /*maxsegz*/0x3ffff,
|
2003-07-01 15:52:06 +00:00
|
|
|
/*flags*/0, /*lockfunc*/busdma_lock_mutex,
|
|
|
|
/*lockarg*/&Giant, &sc->parent_dmat) != 0) {
|
2000-04-02 07:41:17 +00:00
|
|
|
device_printf(dev, "unable to create dma tag\n");
|
|
|
|
goto bad;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (emu_init(sc) == -1) {
|
|
|
|
device_printf(dev, "unable to initialize the card\n");
|
|
|
|
goto bad;
|
|
|
|
}
|
|
|
|
|
2000-12-18 01:36:41 +00:00
|
|
|
codec = AC97_CREATE(dev, sc, emu_ac97);
|
2000-04-02 07:41:17 +00:00
|
|
|
if (codec == NULL) goto bad;
|
2003-04-20 07:43:09 +00:00
|
|
|
gotmic = (ac97_getcaps(codec) & AC97_CAP_MICCHANNEL) ? 1 : 0;
|
2000-12-18 01:36:41 +00:00
|
|
|
if (mixer_init(dev, ac97_getmixerclass(), codec) == -1) goto bad;
|
2000-04-02 07:41:17 +00:00
|
|
|
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
emu_midiattach(sc);
|
|
|
|
|
2001-10-08 06:10:39 +00:00
|
|
|
i = 0;
|
2004-03-17 17:50:55 +00:00
|
|
|
sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &i,
|
2004-01-11 10:30:56 +00:00
|
|
|
RF_ACTIVE | RF_SHAREABLE);
|
|
|
|
if (!sc->irq ||
|
2004-06-04 16:42:33 +00:00
|
|
|
snd_setup_intr(dev, sc->irq, INTR_MPSAFE, emu_intr, sc, &sc->ih)) {
|
2000-04-02 07:41:17 +00:00
|
|
|
device_printf(dev, "unable to map interrupt\n");
|
|
|
|
goto bad;
|
|
|
|
}
|
|
|
|
|
2004-03-06 15:52:42 +00:00
|
|
|
snprintf(status, SND_STATUSLEN, "at io 0x%lx irq %ld %s",
|
|
|
|
rman_get_start(sc->reg), rman_get_start(sc->irq),
|
|
|
|
PCM_KLDSTRING(snd_emu10k1));
|
2000-04-02 07:41:17 +00:00
|
|
|
|
2004-01-11 10:30:56 +00:00
|
|
|
if (pcm_register(dev, sc, sc->nchans, gotmic ? 3 : 2)) goto bad;
|
|
|
|
for (i = 0; i < sc->nchans; i++)
|
2000-12-18 01:36:41 +00:00
|
|
|
pcm_addchan(dev, PCMDIR_PLAY, &emupchan_class, sc);
|
2003-04-20 07:43:09 +00:00
|
|
|
for (i = 0; i < (gotmic ? 3 : 2); i++)
|
2000-12-18 01:36:41 +00:00
|
|
|
pcm_addchan(dev, PCMDIR_REC, &emurchan_class, sc);
|
2000-04-02 07:41:17 +00:00
|
|
|
|
|
|
|
pcm_setstatus(dev, status);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
bad:
|
2000-09-09 19:21:04 +00:00
|
|
|
if (codec) ac97_destroy(codec);
|
2003-09-02 17:30:40 +00:00
|
|
|
if (sc->reg) bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(0), sc->reg);
|
2000-04-02 07:41:17 +00:00
|
|
|
if (sc->ih) bus_teardown_intr(dev, sc->irq, sc->ih);
|
2001-10-08 06:10:39 +00:00
|
|
|
if (sc->irq) bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
|
2000-09-09 19:21:04 +00:00
|
|
|
if (sc->parent_dmat) bus_dma_tag_destroy(sc->parent_dmat);
|
2001-03-24 23:10:29 +00:00
|
|
|
if (sc->lock) snd_mtxfree(sc->lock);
|
2000-04-02 07:41:17 +00:00
|
|
|
free(sc, M_DEVBUF);
|
|
|
|
return ENXIO;
|
|
|
|
}
|
|
|
|
|
2000-09-05 21:06:11 +00:00
|
|
|
static int
|
|
|
|
emu_pci_detach(device_t dev)
|
|
|
|
{
|
|
|
|
int r;
|
|
|
|
struct sc_info *sc;
|
|
|
|
|
|
|
|
r = pcm_unregister(dev);
|
|
|
|
if (r)
|
|
|
|
return r;
|
|
|
|
|
|
|
|
sc = pcm_getdevinfo(dev);
|
|
|
|
/* shutdown chip */
|
|
|
|
emu_uninit(sc);
|
|
|
|
|
2003-09-02 17:30:40 +00:00
|
|
|
bus_release_resource(dev, SYS_RES_IOPORT, PCIR_BAR(0), sc->reg);
|
2000-09-05 21:06:11 +00:00
|
|
|
bus_teardown_intr(dev, sc->irq, sc->ih);
|
2001-10-08 06:10:39 +00:00
|
|
|
bus_release_resource(dev, SYS_RES_IRQ, 0, sc->irq);
|
2000-09-09 19:21:04 +00:00
|
|
|
bus_dma_tag_destroy(sc->parent_dmat);
|
2001-03-24 23:10:29 +00:00
|
|
|
snd_mtxfree(sc->lock);
|
2000-09-05 21:06:11 +00:00
|
|
|
free(sc, M_DEVBUF);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* add suspend, resume */
|
2000-04-02 07:41:17 +00:00
|
|
|
static device_method_t emu_methods[] = {
|
|
|
|
/* Device interface */
|
|
|
|
DEVMETHOD(device_probe, emu_pci_probe),
|
|
|
|
DEVMETHOD(device_attach, emu_pci_attach),
|
2000-09-05 21:06:11 +00:00
|
|
|
DEVMETHOD(device_detach, emu_pci_detach),
|
2000-04-02 07:41:17 +00:00
|
|
|
|
|
|
|
{ 0, 0 }
|
|
|
|
};
|
|
|
|
|
|
|
|
static driver_t emu_driver = {
|
|
|
|
"pcm",
|
|
|
|
emu_methods,
|
2001-08-23 11:30:52 +00:00
|
|
|
PCM_SOFTC_SIZE,
|
2000-04-02 07:41:17 +00:00
|
|
|
};
|
|
|
|
|
2000-07-03 20:52:27 +00:00
|
|
|
DRIVER_MODULE(snd_emu10k1, pci, emu_driver, pcm_devclass, 0, 0);
|
2004-07-16 04:00:08 +00:00
|
|
|
MODULE_DEPEND(snd_emu10k1, sound, SOUND_MINVER, SOUND_PREFVER, SOUND_MAXVER);
|
2000-07-03 20:52:27 +00:00
|
|
|
MODULE_VERSION(snd_emu10k1, 1);
|
Commit the new (old) midi framework. It's based in parts on the NetBSD code,
but large parts are rewritten by matk and tanimura.
This is old code, it's not maintained since 2003. We also don't have a
maintainer for this! Yuriy Tsibizov took it and uses it in his emu10kx
driver. Since the emu10kx driver will enter the tree "soon" (some bugs
have to be fixed after Yuriy return from his holidays), I add it here
already.
This also contains some changes to emu10k1 and cmi, so if you're lucky,
you can now make some kind of use of midi with those soundcards.
To all those poor souls which don't have such a card: feel free to send
patches, we don't have a maintainer for this.
To those which miss a specific feature in the midi code: feel free to
submit patches, we don't have a maintainer for this.
Oh, did I already told that it would be nice if someone would take care
of it? Maintainer with midi equipment wanted! :-)
If you get LOR's, submit a PR and notify multimedia@ please. If you get
panics, submit a PR with a backtrace (compile the sound system into your
kernel instead of using modules in this case) and notify multimedia@
please.
Written by: matk, tanimura
Submitted by: "Yuriy Tsibizov" <Yuriy.Tsibizov@gfk.ru>
Based upon: code from NetBSD
2006-05-27 16:51:37 +00:00
|
|
|
MODULE_DEPEND(snd_emu10k1, midi, 1, 1, 1);
|
2000-06-13 23:24:40 +00:00
|
|
|
|
2000-08-06 18:10:05 +00:00
|
|
|
/* dummy driver to silence the joystick device */
|
2000-06-13 23:24:40 +00:00
|
|
|
static int
|
|
|
|
emujoy_pci_probe(device_t dev)
|
|
|
|
{
|
|
|
|
char *s = NULL;
|
|
|
|
|
|
|
|
switch (pci_get_devid(dev)) {
|
|
|
|
case 0x70021102:
|
|
|
|
s = "Creative EMU10K1 Joystick";
|
|
|
|
device_quiet(dev);
|
|
|
|
break;
|
2001-10-08 06:10:39 +00:00
|
|
|
case 0x70031102:
|
|
|
|
s = "Creative EMU10K2 Joystick";
|
|
|
|
device_quiet(dev);
|
|
|
|
break;
|
2000-06-13 23:24:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (s) device_set_desc(dev, s);
|
2003-04-20 07:43:09 +00:00
|
|
|
return s ? -1000 : ENXIO;
|
2000-06-13 23:24:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
emujoy_pci_attach(device_t dev)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2000-09-05 21:06:11 +00:00
|
|
|
static int
|
|
|
|
emujoy_pci_detach(device_t dev)
|
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2000-06-13 23:24:40 +00:00
|
|
|
static device_method_t emujoy_methods[] = {
|
|
|
|
DEVMETHOD(device_probe, emujoy_pci_probe),
|
|
|
|
DEVMETHOD(device_attach, emujoy_pci_attach),
|
2000-09-05 21:06:11 +00:00
|
|
|
DEVMETHOD(device_detach, emujoy_pci_detach),
|
2000-06-13 23:24:40 +00:00
|
|
|
|
|
|
|
{ 0, 0 }
|
|
|
|
};
|
|
|
|
|
|
|
|
static driver_t emujoy_driver = {
|
|
|
|
"emujoy",
|
|
|
|
emujoy_methods,
|
|
|
|
8,
|
|
|
|
};
|
|
|
|
|
|
|
|
static devclass_t emujoy_devclass;
|
|
|
|
|
|
|
|
DRIVER_MODULE(emujoy, pci, emujoy_driver, emujoy_devclass, 0, 0);
|
|
|
|
|