📄 audio.c
字号:
/*****************************************************************************//* * audio.c -- USB Audio Class driver * * Copyright (C) 1999, 2000, 2001 * Alan Cox (alan@lxorguk.ukuu.org.uk) * Thomas Sailer (sailer@ife.ee.ethz.ch) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Debugging: * Use the 'lsusb' utility to dump the descriptors. * * 1999-09-07: Alan Cox * Parsing Audio descriptor patch * 1999-09-08: Thomas Sailer * Added OSS compatible data io functions; both parts of the * driver remain to be glued together * 1999-09-10: Thomas Sailer * Beautified the driver. Added sample format conversions. * Still not properly glued with the parsing code. * The parsing code seems to have its problems btw, * Since it parses all available configs but doesn't * store which iface/altsetting belongs to which config. * 1999-09-20: Thomas Sailer * Threw out Alan's parsing code and implemented my own one. * You cannot reasonnably linearly parse audio descriptors, * especially the AudioClass descriptors have to be considered * pointer lists. Mixer parsing untested, due to lack of device. * First stab at synch pipe implementation, the Dallas USB DAC * wants to use an Asynch out pipe. usb_audio_state now basically * only contains lists of mixer and wave devices. We can therefore * now have multiple mixer/wave devices per USB device. * 1999-10-28: Thomas Sailer * Converted to URB API. Fixed a taskstate/wakeup semantics mistake * that made the driver consume all available CPU cycles. * Now runs stable on UHCI-Acher/Fliegl/Sailer. * 1999-10-31: Thomas Sailer * Audio can now be unloaded if it is not in use by any mixer * or dsp client (formerly you had to disconnect the audio devices * from the USB port) * Finally, about three months after ordering, my "Maxxtro SPK222" * speakers arrived, isn't disdata a great mail order company 8-) * Parse class specific endpoint descriptor of the audiostreaming * interfaces and take the endpoint attributes from there. * Unbelievably, the Philips USB DAC has a sampling rate range * of over a decade, yet does not support the sampling rate control! * No wonder it sounds so bad, has very audible sampling rate * conversion distortion. Don't try to listen to it using * decent headphones! * "Let's make things better" -> but please Philips start with your * own stuff!!!! * 1999-11-02: Thomas Sailer * It takes the Philips boxes several seconds to acquire synchronisation * that means they won't play short sounds. Should probably maintain * the ISO datastream even if there's nothing to play. * Fix counting the total_bytes counter, RealPlayer G2 depends on it. * 1999-12-20: Thomas Sailer * Fix bad bug in conversion to per interface probing. * disconnect was called multiple times for the audio device, * leading to a premature freeing of the audio structures * 2000-05-13: Thomas Sailer * I don't remember who changed the find_format routine, * but the change was completely broken for the Dallas * chip. Anyway taking sampling rate into account in find_format * is bad and should not be done unless there are devices with * completely broken audio descriptors. Unless someone shows * me such a descriptor, I will not allow find_format to * take the sampling rate into account. * Also, the former find_format made: * - mpg123 play mono instead of stereo * - sox completely fail for wav's with sample rates < 44.1kHz * for the Dallas chip. * Also fix a rather long standing problem with applications that * use "small" writes producing no sound at all. * 2000-05-15: Thomas Sailer * My fears came true, the Philips camera indeed has pretty stupid * audio descriptors. * 2000-05-17: Thomas Sailer * Nemsoft spotted my stupid last minute change, thanks * 2000-05-19: Thomas Sailer * Fixed FEATURE_UNIT thinkos found thanks to the KC Technology * Xtend device. Basically the driver treated FEATURE_UNIT's sourced * by mono terminals as stereo. * 2000-05-20: Thomas Sailer * SELECTOR support (and thus selecting record channels from the mixer). * Somewhat peculiar due to OSS interface limitations. Only works * for channels where a "slider" is already in front of it (i.e. * a MIXER unit or a FEATURE unit with volume capability). * 2000-11-26: Thomas Sailer * Workaround for Dallas DS4201. The DS4201 uses PCM8 as format tag for * its 8 bit modes, but expects signed data (and should therefore have used PCM). * 2001-03-10: Thomas Sailer * provide abs function, prevent picking up a bogus kernel macro * for abs. Bug report by Andrew Morton <andrewm@uow.edu.au> * 2001-06-16: Bryce Nesbitt <bryce@obviously.com> * Fix SNDCTL_DSP_STEREO API violation *//* * Strategy: * * Alan Cox and Thomas Sailer are starting to dig at opposite ends and * are hoping to meet in the middle, just like tunnel diggers :) * Alan tackles the descriptor parsing, Thomas the actual data IO and the * OSS compatible interface. * * Data IO implementation issues * * A mmap'able ring buffer per direction is implemented, because * almost every OSS app expects it. It is however impractical to * transmit/receive USB data directly into and out of the ring buffer, * due to alignment and synchronisation issues. Instead, the ring buffer * feeds a constant time delay line that handles the USB issues. * * Now we first try to find an alternate setting that exactly matches * the sample format requested by the user. If we find one, we do not * need to perform any sample rate conversions. If there is no matching * altsetting, we choose the closest one and perform sample format * conversions. We never do sample rate conversion; these are too * expensive to be performed in the kernel. * * Current status: * - Pretty stable on UHCI-Acher/Fliegl/Sailer * - Does not work on OHCI due to lack of OHCI driver supporting URB's * * Generally: Due to the brokenness of the Audio Class spec * it seems generally impossible to write a generic Audio Class driver, * so a reasonable driver should implement the features that are actually * used. * * Parsing implementation issues * * One cannot reasonably parse the AudioClass descriptors linearly. * Therefore the current implementation features routines to look * for a specific descriptor in the descriptor list. * * How does the parsing work? First, all interfaces are searched * for an AudioControl class interface. If found, the config descriptor * that belongs to the current configuration is fetched from the device. * Then the HEADER descriptor is fetched. It contains a list of * all AudioStreaming and MIDIStreaming devices. This list is then walked, * and all AudioStreaming interfaces are classified into input and output * interfaces (according to the endpoint0 direction in altsetting1) (MIDIStreaming * is currently not supported). The input & output list is then used * to group inputs and outputs together and issued pairwise to the * AudioStreaming class parser. Finally, all OUTPUT_TERMINAL descriptors * are walked and issued to the mixer construction routine. * * The AudioStreaming parser simply enumerates all altsettings belonging * to the specified interface. It looks for AS_GENERAL and FORMAT_TYPE * class specific descriptors to extract the sample format/sample rate * data. Only sample format types PCM and PCM8 are supported right now, and * only FORMAT_TYPE_I is handled. The isochronous data endpoint needs to * be the first endpoint of the interface, and the optional synchronisation * isochronous endpoint the second one. * * Mixer construction works as follows: The various TERMINAL and UNIT * descriptors span a tree from the root (OUTPUT_TERMINAL) through the * intermediate nodes (UNITs) to the leaves (INPUT_TERMINAL). We walk * that tree in a depth first manner. FEATURE_UNITs may contribute volume, * bass and treble sliders to the mixer, MIXER_UNITs volume sliders. * The terminal type encoded in the INPUT_TERMINALs feeds a heuristic * to determine "meaningful" OSS slider numbers, however we will see * how well this works in practice. Other features are not used at the * moment, they seem less often used. Also, it seems difficult at least * to construct recording source switches from SELECTOR_UNITs, but * since there are not many USB ADC's available, we leave that for later. *//*****************************************************************************/#include <linux/version.h>#include <linux/kernel.h>#include <linux/slab.h>#include <linux/string.h>#include <linux/timer.h>#include <linux/sched.h>#include <linux/smp_lock.h>#include <linux/module.h>#include <linux/sound.h>#include <linux/soundcard.h>#include <linux/list.h>#include <linux/vmalloc.h>#include <linux/wrapper.h>#include <linux/init.h>#include <linux/poll.h>#include <linux/bitops.h>#include <asm/uaccess.h>#include <asm/io.h>#include <linux/usb.h>#include "audio.h"/* * Version Information */#define DRIVER_VERSION "v1.0.0"#define DRIVER_AUTHOR "Alan Cox <alan@lxorguk.ukuu.org.uk>, Thomas Sailer (sailer@ife.ee.ethz.ch)"#define DRIVER_DESC "USB Audio Class driver"#define AUDIO_DEBUG 1#define SND_DEV_DSP16 5 #define dprintk(x)#undef absextern int abs(int __x) __attribute__ ((__const__)); /* Shut up warning *//* --------------------------------------------------------------------- *//* * Linked list of all audio devices... */static struct list_head audiodevs = LIST_HEAD_INIT(audiodevs);static DECLARE_MUTEX(open_sem);/* * wait queue for processes wanting to open an USB audio device */static DECLARE_WAIT_QUEUE_HEAD(open_wait);#define MAXFORMATS MAX_ALT#define DMABUFSHIFT 17 /* 128k worth of DMA buffer */#define NRSGBUF (1U<<(DMABUFSHIFT-PAGE_SHIFT))/* * This influences: * - Latency * - Interrupt rate * - Synchronisation behaviour * Don't touch this if you don't understand all of the above. */#define DESCFRAMES 5#define SYNCFRAMES DESCFRAMES#define MIXFLG_STEREOIN 1#define MIXFLG_STEREOOUT 2struct mixerchannel { __u16 value; __u16 osschannel; /* number of the OSS channel */ __s16 minval, maxval; __u16 slctunitid; __u8 unitid; __u8 selector; __u8 chnum; __u8 flags;};struct audioformat { unsigned int format; unsigned int sratelo; unsigned int sratehi; unsigned char altsetting; unsigned char attributes;};struct dmabuf { /* buffer data format */ unsigned int format; unsigned int srate; /* physical buffer */ unsigned char *sgbuf[NRSGBUF]; unsigned bufsize; unsigned numfrag; unsigned fragshift; unsigned wrptr, rdptr; unsigned total_bytes; int count; unsigned error; /* over/underrun */ wait_queue_head_t wait; /* redundant, but makes calculations easier */ unsigned fragsize; unsigned dmasize; /* OSS stuff */ unsigned mapped:1; unsigned ready:1; unsigned ossfragshift; int ossmaxfrags; unsigned subdivision;};struct usb_audio_state;#define FLG_URB0RUNNING 1#define FLG_URB1RUNNING 2#define FLG_SYNC0RUNNING 4#define FLG_SYNC1RUNNING 8#define FLG_RUNNING 16#define FLG_CONNECTED 32struct my_data_urb { urb_t urb; iso_packet_descriptor_t isoframe[DESCFRAMES];};struct my_sync_urb { urb_t urb; iso_packet_descriptor_t isoframe[SYNCFRAMES];};struct usb_audiodev { struct list_head list; struct usb_audio_state *state; /* soundcore stuff */ int dev_audio; /* wave stuff */ mode_t open_mode; spinlock_t lock; /* DMA buffer access spinlock */ struct usbin { int interface; /* Interface number, -1 means not used */ unsigned int format; /* USB data format */ unsigned int datapipe; /* the data input pipe */ unsigned int syncpipe; /* the synchronisation pipe - 0 for anything but adaptive IN mode */ unsigned int syncinterval; /* P for adaptive IN mode, 0 otherwise */ unsigned int freqn; /* nominal sampling rate in USB format, i.e. fs/1000 in Q10.14 */ unsigned int freqmax; /* maximum sampling rate, used for buffer management */ unsigned int phase; /* phase accumulator */ unsigned int flags; /* see FLG_ defines */ struct my_data_urb durb[2]; /* ISO descriptors for the data endpoint */ struct my_sync_urb surb[2]; /* ISO sync pipe descriptor if needed */ struct dmabuf dma; } usbin; struct usbout { int interface; /* Interface number, -1 means not used */ unsigned int format; /* USB data format */ unsigned int datapipe; /* the data input pipe */ unsigned int syncpipe; /* the synchronisation pipe - 0 for anything but asynchronous OUT mode */ unsigned int syncinterval; /* P for asynchronous OUT mode, 0 otherwise */ unsigned int freqn; /* nominal sampling rate in USB format, i.e. fs/1000 in Q10.14 */ unsigned int freqm; /* momentary sampling rate in USB format, i.e. fs/1000 in Q10.14 */ unsigned int freqmax; /* maximum sampling rate, used for buffer management */ unsigned int phase; /* phase accumulator */ unsigned int flags; /* see FLG_ defines */ struct my_data_urb durb[2]; /* ISO descriptors for the data endpoint */ struct my_sync_urb surb[2]; /* ISO sync pipe descriptor if needed */ struct dmabuf dma; } usbout; unsigned int numfmtin, numfmtout; struct audioformat fmtin[MAXFORMATS]; struct audioformat fmtout[MAXFORMATS];}; struct usb_mixerdev { struct list_head list; struct usb_audio_state *state; /* soundcore stuff */ int dev_mixer; unsigned char iface; /* interface number of the AudioControl interface */ /* USB format descriptions */ unsigned int numch, modcnt; /* mixch is last and gets allocated dynamically */ struct mixerchannel ch[0];};struct usb_audio_state { struct list_head audiodev; /* USB device */ struct usb_device *usbdev; struct list_head audiolist; struct list_head mixerlist; unsigned count; /* usage counter; NOTE: the usb stack is also considered a user */};/* private audio format extensions */#define AFMT_STEREO 0x80000000#define AFMT_ISSTEREO(x) ((x) & AFMT_STEREO)#define AFMT_IS16BIT(x) ((x) & (AFMT_S16_LE|AFMT_S16_BE|AFMT_U16_LE|AFMT_U16_BE))#define AFMT_ISUNSIGNED(x) ((x) & (AFMT_U8|AFMT_U16_LE|AFMT_U16_BE))#define AFMT_BYTESSHIFT(x) ((AFMT_ISSTEREO(x) ? 1 : 0) + (AFMT_IS16BIT(x) ? 1 : 0))#define AFMT_BYTES(x) (1<<AFMT_BYTESSHFIT(x))/* --------------------------------------------------------------------- *//* prevent picking up a bogus abs macro */#undef absextern inline int abs(int x){ if (x < 0) return -x; return x;} /* --------------------------------------------------------------------- */extern inline unsigned ld2(unsigned int x){ unsigned r = 0; if (x >= 0x10000) { x >>= 16; r += 16; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -