diff options
author | Markus Grabner <grabner@icg.tugraz.at> | 2010-08-11 23:35:30 (GMT) |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-08-31 22:28:15 (GMT) |
commit | 1027f476f507ef7ed9919cd3e3d32310f3985da1 (patch) | |
tree | 5f0da58a5bc15338c71e848693a5ae259b97a207 /drivers/staging/line6/pcm.h | |
parent | 4498dbcd2d85b67e9f46790bcfee5860d2dd1762 (diff) | |
download | linux-fsl-qoriq-1027f476f507ef7ed9919cd3e3d32310f3985da1.tar.xz |
staging: line6: sync with upstream
Big upstream sync.
Signed-off-by: Markus Grabner <grabner@icg.tugraz.at>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/line6/pcm.h')
-rw-r--r-- | drivers/staging/line6/pcm.h | 135 |
1 files changed, 119 insertions, 16 deletions
diff --git a/drivers/staging/line6/pcm.h b/drivers/staging/line6/pcm.h index 53db217..c9ff95a 100644 --- a/drivers/staging/line6/pcm.h +++ b/drivers/staging/line6/pcm.h @@ -1,7 +1,7 @@ /* - * Line6 Linux USB driver - 0.8.0 + * Line6 Linux USB driver - 0.9.0 * - * Copyright (C) 2004-2009 Markus Grabner (grabner@icg.tugraz.at) + * Copyright (C) 2004-2010 Markus Grabner (grabner@icg.tugraz.at) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -24,30 +24,79 @@ /* number of URBs */ -#define LINE6_ISO_BUFFERS 8 +#define LINE6_ISO_BUFFERS 2 -/* number of USB frames per URB */ -#define LINE6_ISO_PACKETS 2 +/* + number of USB frames per URB + The Line6 Windows driver always transmits two frames per packet, but + the Linux driver performs significantly better (i.e., lower latency) + with only one frame per packet. +*/ +#define LINE6_ISO_PACKETS 1 /* in a "full speed" device (such as the PODxt Pro) this means 1ms */ #define LINE6_ISO_INTERVAL 1 -/* this should be queried dynamically from the USB interface! */ -#define LINE6_ISO_PACKET_SIZE_MAX 252 +#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE +#define LINE6_IMPULSE_DEFAULT_PERIOD 100 +#endif + +#define LINE6_BACKUP_MONITOR_SIGNAL 0 +#define LINE6_REUSE_DMA_AREA_FOR_PLAYBACK 0 /* - Extract the messaging device from the substream instance + Get substream from Line6 PCM data structure */ -#define s2m(s) (((struct snd_line6_pcm *) \ - snd_pcm_substream_chip(s))->line6->ifcdev) +#define get_substream(line6pcm, stream) (line6pcm->pcm->streams[stream].substream) +/* + PCM mode bits and masks. + "ALSA": operations triggered by applications via ALSA + "MONITOR": software monitoring + "IMPULSE": optional impulse response operation +*/ enum { - BIT_RUNNING_PLAYBACK, - BIT_RUNNING_CAPTURE, + /* individual bits: */ + BIT_PCM_ALSA_PLAYBACK, + BIT_PCM_ALSA_CAPTURE, + BIT_PCM_MONITOR_PLAYBACK, + BIT_PCM_MONITOR_CAPTURE, +#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE + BIT_PCM_IMPULSE_PLAYBACK, + BIT_PCM_IMPULSE_CAPTURE, +#endif BIT_PAUSE_PLAYBACK, - BIT_PREPARED + BIT_PREPARED, + + /* individual masks: */ + MASK_PCM_ALSA_PLAYBACK = 1 << BIT_PCM_ALSA_PLAYBACK, + MASK_PCM_ALSA_CAPTURE = 1 << BIT_PCM_ALSA_CAPTURE, + MASK_PCM_MONITOR_PLAYBACK = 1 << BIT_PCM_MONITOR_PLAYBACK, + MASK_PCM_MONITOR_CAPTURE = 1 << BIT_PCM_MONITOR_CAPTURE, +#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE + MASK_PCM_IMPULSE_PLAYBACK = 1 << BIT_PCM_IMPULSE_PLAYBACK, + MASK_PCM_IMPULSE_CAPTURE = 1 << BIT_PCM_IMPULSE_CAPTURE, +#endif + MASK_PAUSE_PLAYBACK = 1 << BIT_PAUSE_PLAYBACK, + MASK_PREPARED = 1 << BIT_PREPARED, + + /* combined masks (by operation): */ + MASK_PCM_ALSA = MASK_PCM_ALSA_PLAYBACK | MASK_PCM_ALSA_CAPTURE, + MASK_PCM_MONITOR = MASK_PCM_MONITOR_PLAYBACK | MASK_PCM_MONITOR_CAPTURE, +#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE + MASK_PCM_IMPULSE = MASK_PCM_IMPULSE_PLAYBACK | MASK_PCM_IMPULSE_CAPTURE, +#endif + + /* combined masks (by direction): */ +#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE + MASK_PLAYBACK = MASK_PCM_ALSA_PLAYBACK | MASK_PCM_MONITOR_PLAYBACK | MASK_PCM_IMPULSE_PLAYBACK, + MASK_CAPTURE = MASK_PCM_ALSA_CAPTURE | MASK_PCM_MONITOR_CAPTURE | MASK_PCM_IMPULSE_CAPTURE +#else + MASK_PLAYBACK = MASK_PCM_ALSA_PLAYBACK | MASK_PCM_MONITOR_PLAYBACK, + MASK_CAPTURE = MASK_PCM_ALSA_CAPTURE | MASK_PCM_MONITOR_CAPTURE +#endif }; struct line6_pcm_properties { @@ -83,9 +132,11 @@ struct snd_line6_pcm { struct urb *urb_audio_in[LINE6_ISO_BUFFERS]; /** - Temporary buffer to hold data when playback buffer wraps. + Temporary buffer for playback. + Since the packet size is not known in advance, this buffer is + large enough to store maximum size packets. */ - unsigned char *wrap_out; + unsigned char *buffer_out; /** Temporary buffer for capture. @@ -95,6 +146,21 @@ struct snd_line6_pcm { unsigned char *buffer_in; /** + Temporary buffer index for playback. + */ + int index_out; + + /** + Previously captured frame (for software monitoring). + */ + unsigned char *prev_fbuf; + + /** + Size of previously captured frame (for software monitoring). + */ + int prev_fsize; + + /** Free frame position in the playback buffer. */ snd_pcm_uframes_t pos_out; @@ -204,12 +270,36 @@ struct snd_line6_pcm { /** PCM playback volume (left and right). */ - int volume[2]; + int volume_playback[2]; + + /** + PCM monitor volume. + */ + int volume_monitor; + +#ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE + /** + Volume of impulse response test signal (if zero, test is disabled). + */ + int impulse_volume; + + /** + Period of impulse response test signal. + */ + int impulse_period; + + /** + Counter for impulse response test signal. + */ + int impulse_count; +#endif /** Several status bits (see BIT_*). */ unsigned long flags; + + int last_frame_in, last_frame_out; }; @@ -217,6 +307,19 @@ extern int line6_init_pcm(struct usb_line6 *line6, struct line6_pcm_properties *properties); extern int snd_line6_trigger(struct snd_pcm_substream *substream, int cmd); extern int snd_line6_prepare(struct snd_pcm_substream *substream); +extern void line6_pcm_disconnect(struct snd_line6_pcm *line6pcm); +extern int line6_pcm_start(struct snd_line6_pcm *line6pcm, int channels); +extern int line6_pcm_stop(struct snd_line6_pcm *line6pcm, int channels); + + +#define PRINT_FRAME_DIFF(op) { \ + static int diff_prev = 1000; \ + int diff = line6pcm->last_frame_out - line6pcm->last_frame_in; \ + if((diff != diff_prev) && (abs(diff) < 100)) { \ + printk("%s frame diff = %d\n", op, diff); \ + diff_prev = diff; \ + } \ + } #endif |